sql-toolkit
Version:
A SQL Toolkit based on pure business objects passed to and from stateful data access objects
1,203 lines (1,186 loc) • 45.7 kB
JavaScript
const Order = require('../../examples/order/bo/order');
const Article = require('../../examples/blog/bo/article');
const Articles = require('../../examples/blog/bo/articles');
test('Bo#parseFromDatabase where multiple rows reduce to one nested object (with all one-to-one or one-to-many tables)', () => {
const results = [{
'order#id': 3866,
'order#email': 'email@example.com',
'order#browser_ip': void 0,
'order#browser_user_agent': void 0,
'order#kujo_imported_date': '2018-08-13 12:40:05.909355-04',
'order#created_date': '2018-06-08 17:51:27-04',
'order#cancel_reason': void 0,
'order#cancelled_date': void 0,
'order#closed_date': '2018-06-11 17:34:27-04',
'order#processed_date': '2018-06-08 17:51:27-04',
'order#updated_date': '2018-06-13 15:41:55-04',
'order#note': void 0,
'order#subtotal_price': 0.00,
'order#taxes_included': false,
'order#total_discounts': 625.00,
'order#total_price': 0.00,
'order#total_tax': 0.00,
'order#total_weight': 0,
'order#order_status_url': 'example.com/order',
'order#utm_source_id': 6,
'order#utm_medium_id': void 0,
'order#utm_campaign': void 0,
'order#utm_content': void 0,
'order#utm_term': void 0,
'utm_source#id': 6,
'utm_source#value': 'instagram',
'utm_source#label': 'Instagram',
'utm_source#internal': true,
'line_item#id': 2271,
'line_item#fulfillment_status_id': 7,
'line_item#product_variant_id': 163,
'line_item#order_id': 3866,
'line_item#fulfillable_quantity': 0,
'line_item#fulfillment_service': 'manual',
'line_item#grams': 0,
'line_item#price': 120.00,
'line_item#quantity': 1,
'line_item#requires_shipping': void 0,
'line_item#taxable': true,
'line_item#total_discount': 0.00,
'product_variant#id': 163,
'product_variant#product_id': 1,
'product_variant#actual_product_variant_id': 98,
'product_variant#color_id': 3,
'product_variant#gender_id': 1,
'product_variant#size_id': 11,
'product_variant#barcode': void 0,
'product_variant#price': 120,
'product_variant#compare_at_price': 120,
'product_variant#created_date': '2018-07-17 13:20:29.202352-04',
'product_variant#updated_date': '2018-07-17 13:20:29.202352-04',
'product_variant#grams': void 0,
'product_variant#requires_shipping': void 0,
'product#id': 1,
'product#vendor_id': 1,
'product#value': 'mens_yard_shoes',
'product#label': 'Mens Yard Shoes',
'product#product_type': 'shoes',
'product#created_date': '2018-06-21 12:38:39.021271-04',
'product#updated_date': '2018-06-21 12:38:39.021271-04',
'product#published_date': void 0,
'product#category': void 0,
}, {
'order#id': 3866,
'order#email': 'email@example.com',
'order#browser_ip': void 0,
'order#browser_user_agent': void 0,
'order#kujo_imported_date': '2018-08-13 12:40:05.909355-04',
'order#created_date': '2018-06-08 17:51:27-04',
'order#cancel_reason': void 0,
'order#cancelled_date': void 0,
'order#closed_date': '2018-06-11 17:34:27-04',
'order#processed_date': '2018-06-08 17:51:27-04',
'order#updated_date': '2018-06-13 15:41:55-04',
'order#note': void 0,
'order#subtotal_price': 0.00,
'order#taxes_included': false,
'order#total_discounts': 625.00,
'order#total_price': 0.00,
'order#total_tax': 0.00,
'order#total_weight': 0,
'order#order_status_url': 'example.com/order',
'order#utm_source_id': 6,
'order#utm_medium_id': void 0,
'order#utm_campaign': void 0,
'order#utm_content': void 0,
'order#utm_term': void 0,
'utm_source#id': 6,
'utm_source#value': 'instagram',
'utm_source#label': 'Instagram',
'utm_source#internal': true,
'line_item#id': 2272,
'line_item#fulfillment_status_id': 7,
'line_item#product_variant_id': 186,
'line_item#order_id': 3866,
'line_item#fulfillable_quantity': 0,
'line_item#fulfillment_service': 'manual',
'line_item#grams': 0,
'line_item#price': 120.00,
'line_item#quantity': 1,
'line_item#requires_shipping': void 0,
'line_item#taxable': true,
'line_item#total_discount': 0.00,
'product_variant#id': 186,
'product_variant#product_id': 1,
'product_variant#actual_product_variant_id': 111,
'product_variant#color_id': 4,
'product_variant#gender_id': 1,
'product_variant#size_id': 11,
'product_variant#barcode': void 0,
'product_variant#price': 120,
'product_variant#compare_at_price': 120,
'product_variant#created_date': '2018-07-17 13:20:29.236344-04',
'product_variant#updated_date': '2018-07-17 13:20:29.236344-04',
'product_variant#grams': void 0,
'product_variant#requires_shipping': void 0,
'product#id': 1,
'product#vendor_id': 1,
'product#value': 'mens_yard_shoes',
'product#label': 'Mens Yard Shoes',
'product#product_type': 'shoes',
'product#created_date': '2018-06-21 12:38:39.021271-04',
'product#updated_date': '2018-06-21 12:38:39.021271-04',
'product#published_date': void 0,
'product#category': void 0,
}, {
'order#id': 3866,
'order#email': 'email@example.com',
'order#browser_ip': void 0,
'order#browser_user_agent': void 0,
'order#kujo_imported_date': '2018-08-13 12:40:05.909355-04',
'order#created_date': '2018-06-08 17:51:27-04',
'order#cancel_reason': void 0,
'order#cancelled_date': void 0,
'order#closed_date': '2018-06-11 17:34:27-04',
'order#processed_date': '2018-06-08 17:51:27-04',
'order#updated_date': '2018-06-13 15:41:55-04',
'order#note': void 0,
'order#subtotal_price': 0.00,
'order#taxes_included': false,
'order#total_discounts': 625.00,
'order#total_price': 0.00,
'order#total_tax': 0.00,
'order#total_weight': 0,
'order#order_status_url': 'example.com/order',
'order#utm_source_id': 6,
'order#utm_medium_id': void 0,
'order#utm_campaign': void 0,
'order#utm_content': void 0,
'order#utm_term': void 0,
'utm_source#id': 6,
'utm_source#value': 'instagram',
'utm_source#label': 'Instagram',
'utm_source#internal': true,
'line_item#id': 2273,
'line_item#fulfillment_status_id': 7,
'line_item#product_variant_id': 213,
'line_item#order_id': 3866,
'line_item#fulfillable_quantity': 0,
'line_item#fulfillment_service': 'manual',
'line_item#grams': 0,
'line_item#price': 120.00,
'line_item#quantity': 1,
'line_item#requires_shipping': void 0,
'line_item#taxable': true,
'line_item#total_discount': 0.00,
'product_variant#id': 213,
'product_variant#product_id': 1,
'product_variant#actual_product_variant_id': 127,
'product_variant#color_id': 1,
'product_variant#gender_id': 1,
'product_variant#size_id': 11,
'product_variant#barcode': void 0,
'product_variant#price': 120,
'product_variant#compare_at_price': 120,
'product_variant#created_date': '2018-07-17 13:20:29.27225-04',
'product_variant#updated_date': '2018-07-17 13:20:29.27225-04',
'product_variant#grams': void 0,
'product_variant#requires_shipping': void 0,
'product#id': 1,
'product#vendor_id': 1,
'product#value': 'mens_yard_shoes',
'product#label': 'Mens Yard Shoes',
'product#product_type': 'shoes',
'product#created_date': '2018-06-21 12:38:39.021271-04',
'product#updated_date': '2018-06-21 12:38:39.021271-04',
'product#published_date': void 0,
'product#category': void 0,
}, {
'order#id': 3866,
'order#email': 'email@example.com',
'order#browser_ip': void 0,
'order#browser_user_agent': void 0,
'order#kujo_imported_date': '2018-08-13 12:40:05.909355-04',
'order#created_date': '2018-06-08 17:51:27-04',
'order#cancel_reason': void 0,
'order#cancelled_date': void 0,
'order#closed_date': '2018-06-11 17:34:27-04',
'order#processed_date': '2018-06-08 17:51:27-04',
'order#updated_date': '2018-06-13 15:41:55-04',
'order#note': void 0,
'order#subtotal_price': 0.00,
'order#taxes_included': false,
'order#total_discounts': 625.00,
'order#total_price': 0.00,
'order#total_tax': 0.00,
'order#total_weight': 0,
'order#order_status_url': 'example.com/order',
'order#utm_source_id': 6,
'order#utm_medium_id': void 0,
'order#utm_campaign': void 0,
'order#utm_content': void 0,
'order#utm_term': void 0,
'utm_source#id': 6,
'utm_source#value': 'instagram',
'utm_source#label': 'Instagram',
'utm_source#internal': true,
'line_item#id': 2274,
'line_item#fulfillment_status_id': 7,
'line_item#product_variant_id': 207,
'line_item#order_id': 3866,
'line_item#fulfillable_quantity': 0,
'line_item#fulfillment_service': 'manual',
'line_item#grams': 0,
'line_item#price': 120.00,
'line_item#quantity': 1,
'line_item#requires_shipping': void 0,
'line_item#taxable': true,
'line_item#total_discount': 0.00,
'product_variant#id': 207,
'product_variant#product_id': 1,
'product_variant#actual_product_variant_id': 124,
'product_variant#color_id': 1,
'product_variant#gender_id': 1,
'product_variant#size_id': 8,
'product_variant#barcode': void 0,
'product_variant#price': 120,
'product_variant#compare_at_price': 120,
'product_variant#created_date': '2018-07-17 13:20:29.261909-04',
'product_variant#updated_date': '2018-07-17 13:20:29.261909-04',
'product_variant#grams': void 0,
'product_variant#requires_shipping': void 0,
'product#id': 1,
'product#vendor_id': 1,
'product#value': 'mens_yard_shoes',
'product#label': 'Mens Yard Shoes',
'product#product_type': 'shoes',
'product#created_date': '2018-06-21 12:38:39.021271-04',
'product#updated_date': '2018-06-21 12:38:39.021271-04',
'product#published_date': void 0,
'product#category': void 0,
}, {
'order#id': 3866,
'order#email': 'email@example.com',
'order#browser_ip': void 0,
'order#browser_user_agent': void 0,
'order#kujo_imported_date': '2018-08-13 12:40:05.909355-04',
'order#created_date': '2018-06-08 17:51:27-04',
'order#cancel_reason': void 0,
'order#cancelled_date': void 0,
'order#closed_date': '2018-06-11 17:34:27-04',
'order#processed_date': '2018-06-08 17:51:27-04',
'order#updated_date': '2018-06-13 15:41:55-04',
'order#note': void 0,
'order#subtotal_price': 0.00,
'order#taxes_included': false,
'order#total_discounts': 625.00,
'order#total_price': 0.00,
'order#total_tax': 0.00,
'order#total_weight': 0,
'order#order_status_url': 'example.com/order',
'order#utm_source_id': 6,
'order#utm_medium_id': void 0,
'order#utm_campaign': void 0,
'order#utm_content': void 0,
'order#utm_term': void 0,
'utm_source#id': 6,
'utm_source#value': 'instagram',
'utm_source#label': 'Instagram',
'utm_source#internal': true,
'line_item#id': 2275,
'line_item#fulfillment_status_id': 7,
'line_item#product_variant_id': 296,
'line_item#order_id': 3866,
'line_item#fulfillable_quantity': 0,
'line_item#fulfillment_service': 'manual',
'line_item#grams': 0,
'line_item#price': 25.00,
'line_item#quantity': 1,
'line_item#requires_shipping': void 0,
'line_item#taxable': true,
'line_item#total_discount': 0.00,
'product_variant#id': 296,
'product_variant#product_id': 5,
'product_variant#actual_product_variant_id': 144,
'product_variant#color_id': 5,
'product_variant#gender_id': 3,
'product_variant#size_id': 21,
'product_variant#barcode': void 0,
'product_variant#price': 120,
'product_variant#compare_at_price': 120,
'product_variant#created_date': '2018-07-17 13:20:29.387943-04',
'product_variant#updated_date': '2018-07-17 13:20:29.387943-04',
'product_variant#grams': void 0,
'product_variant#requires_shipping': void 0,
'product#id': 5,
'product#vendor_id': 1,
'product#value': 'relaxed_tee',
'product#label': 'Relaxed Tee',
'product#product_type': 'shirts',
'product#created_date': '2018-06-21 12:44:30.640995-04',
'product#updated_date': '2018-06-21 12:44:30.640995-04',
'product#published_date': void 0,
'product#category': void 0,
}, {
'order#id': 3866,
'order#email': 'email@example.com',
'order#browser_ip': void 0,
'order#browser_user_agent': void 0,
'order#kujo_imported_date': '2018-08-13 12:40:05.909355-04',
'order#created_date': '2018-06-08 17:51:27-04',
'order#cancel_reason': void 0,
'order#cancelled_date': void 0,
'order#closed_date': '2018-06-11 17:34:27-04',
'order#processed_date': '2018-06-08 17:51:27-04',
'order#updated_date': '2018-06-13 15:41:55-04',
'order#note': void 0,
'order#subtotal_price': 0.00,
'order#taxes_included': false,
'order#total_discounts': 625.00,
'order#total_price': 0.00,
'order#total_tax': 0.00,
'order#total_weight': 0,
'order#order_status_url': 'example.com/order',
'order#utm_source_id': 6,
'order#utm_medium_id': void 0,
'order#utm_campaign': void 0,
'order#utm_content': void 0,
'order#utm_term': void 0,
'utm_source#id': 6,
'utm_source#value': 'instagram',
'utm_source#label': 'Instagram',
'utm_source#internal': true,
'line_item#id': 2276,
'line_item#fulfillment_status_id': 7,
'line_item#product_variant_id': 308,
'line_item#order_id': 3866,
'line_item#fulfillable_quantity': 0,
'line_item#fulfillment_service': 'manual',
'line_item#grams': 0,
'line_item#price': 120.00,
'line_item#quantity': 1,
'line_item#requires_shipping': void 0,
'line_item#taxable': true,
'line_item#total_discount': 0.00,
'product_variant#id': 308,
'product_variant#product_id': 3,
'product_variant#actual_product_variant_id': 157,
'product_variant#color_id': 2,
'product_variant#gender_id': 2,
'product_variant#size_id': 4,
'product_variant#barcode': void 0,
'product_variant#price': 120,
'product_variant#compare_at_price': 120,
'product_variant#created_date': '2018-08-20 22:58:48.817847-04',
'product_variant#updated_date': '2018-08-20 22:58:48.817847-04',
'product_variant#grams': void 0,
'product_variant#requires_shipping': void 0,
'product#id': 3,
'product#vendor_id': 1,
'product#value': 'womens_yard_shoes',
'product#label': 'Womens Yard Shoes',
'product#product_type': 'shoes',
'product#created_date': '2018-06-21 12:44:30.631046-04',
'product#updated_date': '2018-06-21 12:44:30.631046-04',
'product#published_date': void 0,
'product#category': void 0,
}];
const order = Order.createOneFromDatabase(results);
expect(Array.isArray(order)).toBe(false);
expect(order.id).toEqual(3866);
expect(order.utmSource.id).toEqual(6);
expect(order.lineItems.models.length).toEqual(6);
expect(order.lineItems.models[0].id).toEqual(2271);
expect(order.lineItems.models[0].productVariant.id).toEqual(163);
expect(order.lineItems.models[0].productVariant.product.id).toEqual(1);
expect(order.lineItems.models[1].id).toEqual(2272);
expect(order.lineItems.models[1].productVariant.id).toEqual(186);
expect(order.lineItems.models[1].productVariant.product.id).toEqual(1);
expect(order.lineItems.models[2].id).toEqual(2273);
expect(order.lineItems.models[2].productVariant.id).toEqual(213);
expect(order.lineItems.models[2].productVariant.product.id).toEqual(1);
expect(order.lineItems.models[3].id).toEqual(2274);
expect(order.lineItems.models[3].productVariant.id).toEqual(207);
expect(order.lineItems.models[3].productVariant.product.id).toEqual(1);
expect(order.lineItems.models[4].id).toEqual(2275);
expect(order.lineItems.models[4].productVariant.id).toEqual(296);
expect(order.lineItems.models[4].productVariant.product.id).toEqual(5);
expect(order.lineItems.models[5].id).toEqual(2276);
expect(order.lineItems.models[5].productVariant.id).toEqual(308);
expect(order.lineItems.models[5].productVariant.product.id).toEqual(3);
});
test('Bo#parseFromDatabase where multiple rows reduce to one nested object (with many-to-many tables)', () => {
const results = [{
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 36,
'article_tag#article_id': 14,
'article_tag#tag_id': 3,
'tag#id': 3,
'tag#name': 'Do-It-Yourself',
'tag#slug': 'do-it-yourself'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 37,
'article_tag#article_id': 14,
'article_tag#tag_id': 4,
'tag#id': 4,
'tag#name': 'Family Fun',
'tag#slug': 'family-fun'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 38,
'article_tag#article_id': 14,
'article_tag#tag_id': 5,
'tag#id': 5,
'tag#name': 'Decorating',
'tag#slug': 'decorating'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 39,
'article_tag#article_id': 14,
'article_tag#tag_id': 6,
'tag#id': 6,
'tag#name': 'Hosting',
'tag#slug': 'hosting'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 40,
'article_tag#article_id': 14,
'article_tag#tag_id': 7,
'tag#id': 7,
'tag#name': 'Recipes',
'tag#slug': 'recipes'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 41,
'article_tag#article_id': 14,
'article_tag#tag_id': 8,
'tag#id': 8,
'tag#name': 'Product Reviews',
'tag#slug': 'product-reviews'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 42,
'article_tag#article_id': 14,
'article_tag#tag_id': 9,
'tag#id': 9,
'tag#name': 'Mythbusters',
'tag#slug': 'mythbusters'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 43,
'article_tag#article_id': 14,
'article_tag#tag_id': 11,
'tag#id': 11,
'tag#name': 'Yard Care',
'tag#slug': 'yard-care'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 44,
'article_tag#article_id': 14,
'article_tag#tag_id': 12,
'tag#id': 12,
'tag#name': 'Lifestyle',
'tag#slug': 'lifestyle'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 45,
'article_tag#article_id': 14,
'article_tag#tag_id': 16,
'tag#id': 16,
'tag#name': 'Bar',
'tag#slug': 'bar'
}];
const article = Article.createOneFromDatabase(results);
expect(Array.isArray(article)).toBe(false);
expect(article.id).toEqual(14);
expect(article.person.id).toEqual(8);
expect(article.articleTags.models.length).toEqual(10);
expect(article.articleTags.models[0].id).toEqual(36);
expect(article.articleTags.models[0].tag.id).toEqual(3);
expect(article.articleTags.models[1].id).toEqual(37);
expect(article.articleTags.models[1].tag.id).toEqual(4);
expect(article.articleTags.models[2].id).toEqual(38);
expect(article.articleTags.models[2].tag.id).toEqual(5);
expect(article.articleTags.models[3].id).toEqual(39);
expect(article.articleTags.models[3].tag.id).toEqual(6);
expect(article.articleTags.models[4].id).toEqual(40);
expect(article.articleTags.models[4].tag.id).toEqual(7);
expect(article.articleTags.models[5].id).toEqual(41);
expect(article.articleTags.models[5].tag.id).toEqual(8);
expect(article.articleTags.models[6].id).toEqual(42);
expect(article.articleTags.models[6].tag.id).toEqual(9);
expect(article.articleTags.models[7].id).toEqual(43);
expect(article.articleTags.models[7].tag.id).toEqual(11);
expect(article.articleTags.models[8].id).toEqual(44);
expect(article.articleTags.models[8].tag.id).toEqual(12);
expect(article.articleTags.models[9].id).toEqual(45);
expect(article.articleTags.models[9].tag.id).toEqual(16);
});
test('Bo#parseFromDatabase where multiple rows reduce to many rows with nested objects (with many-to-many tables)', () => {
const results = [{
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 36,
'article_tag#article_id': 14,
'article_tag#tag_id': 3,
'tag#id': 3,
'tag#name': 'Do-It-Yourself',
'tag#slug': 'do-it-yourself'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 37,
'article_tag#article_id': 14,
'article_tag#tag_id': 4,
'tag#id': 4,
'tag#name': 'Family Fun',
'tag#slug': 'family-fun'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 38,
'article_tag#article_id': 14,
'article_tag#tag_id': 5,
'tag#id': 5,
'tag#name': 'Decorating',
'tag#slug': 'decorating'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 39,
'article_tag#article_id': 14,
'article_tag#tag_id': 6,
'tag#id': 6,
'tag#name': 'Hosting',
'tag#slug': 'hosting'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 40,
'article_tag#article_id': 14,
'article_tag#tag_id': 7,
'tag#id': 7,
'tag#name': 'Recipes',
'tag#slug': 'recipes'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 41,
'article_tag#article_id': 14,
'article_tag#tag_id': 8,
'tag#id': 8,
'tag#name': 'Product Reviews',
'tag#slug': 'product-reviews'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 42,
'article_tag#article_id': 14,
'article_tag#tag_id': 9,
'tag#id': 9,
'tag#name': 'Mythbusters',
'tag#slug': 'mythbusters'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 43,
'article_tag#article_id': 14,
'article_tag#tag_id': 11,
'tag#id': 11,
'tag#name': 'Yard Care',
'tag#slug': 'yard-care'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 44,
'article_tag#article_id': 14,
'article_tag#tag_id': 12,
'tag#id': 12,
'tag#name': 'Lifestyle',
'tag#slug': 'lifestyle'
}, {
'article#id': 14,
'article#author_id': 8,
'article#created_date': new Date('2019-01-11T13:42:39.819Z'),
'article#read_time_minutes': 1,
'article#seo_description': 'some seo words',
'article#primary_image': 'https://example.com/8afdf36d95.jpg',
'article#title': 'Some blog',
'article#slug': 'some-blog',
'article#body': '<p>Oh yeah</p>',
'article#amp_body': '<p>Oh yeah</p>',
'article#kind': 'Article',
'article#points': 2,
'person#id': 8,
'person#first_name': 'Brad',
'person#last_name': 'Martin',
'person#slug': 'brad-martin',
'person#email': 'brad@brad.com',
'person#picture': 'https://example.com/brad.jpg',
'person#cover_photo': 'https://example.com/some.jpg',
'person#brand': null,
'person#tagline': 'Dreamer of big things',
'person#display_name': null,
'person#biography': 'Born to party',
'person#title': 'Chief Marketing Officer',
'article_tag#id': 45,
'article_tag#article_id': 14,
'article_tag#tag_id': 16,
'tag#id': 16,
'tag#name': 'Bar',
'tag#slug': 'bar'
}, {
'article#id': 12,
'article#author_id': 17,
'article#created_date': new Date('2018-02-14T19:09:29.628Z'),
'article#read_time_minutes': 5,
'article#seo_description': 'The real reasons',
'article#primary_image': 'https://example.com/e64284f2d0.jpg',
'article#title': '6 Surprising Reasons Why Homeowners Really Work On Their Lawn & Garden',
'article#slug': '6-surprising-reasons-why-homeowners-really-work-on-their-lawn-and-garden',
'article#body': '<p>Why?</p>',
'article#amp_body': '<p>Why?</p>',
'article#kind': 'BlogPosting',
'article#points': 11,
'person#id': 17,
'person#first_name': 'David',
'person#last_name': 'Swift',
'person#slug': 'david-swift',
'person#email': 'swift@swift.com',
'person#picture': 'https://example.com/swift.jpg',
'person#cover_photo': 'https://example.com/cover.jpg',
'person#brand': 'David Swift',
'person#tagline': 'My milkweed brings all the gnomes to the yard',
'person#display_name': 'David Swift',
'person#biography': 'With a garden trowel in one hand',
'person#title': 'Official Blogger',
'article_tag#id': 33,
'article_tag#article_id': 12,
'article_tag#tag_id': 1,
'tag#id': 1,
'tag#name': 'Minute to Fix It',
'tag#slug': 'minute-to-fix-it'
}, {
'article#id': 12,
'article#author_id': 17,
'article#created_date': new Date('2018-02-14T19:09:29.628Z'),
'article#read_time_minutes': 5,
'article#seo_description': 'The real reasons',
'article#primary_image': 'https://example.com/e64284f2d0.jpg',
'article#title': '6 Surprising Reasons Why Homeowners Really Work On Their Lawn & Garden',
'article#slug': '6-surprising-reasons-why-homeowners-really-work-on-their-lawn-and-garden',
'article#body': '<p>Why?</p>',
'article#amp_body': '<p>Why?</p>',
'article#kind': 'BlogPosting',
'article#points': 11,
'person#id': 17,
'person#first_name': 'David',
'person#last_name': 'Swift',
'person#slug': 'david-swift',
'person#email': 'swift@swift.com',
'person#picture': 'https://example.com/swift.jpg',
'person#cover_photo': 'https://example.com/cover.jpg',
'person#brand': 'David Swift',
'person#tagline': 'My milkweed brings all the gnomes to the yard',
'person#display_name': 'David Swift',
'person#biography': 'With a garden trowel in one hand',
'person#title': 'Official Blogger',
'article_tag#id': 34,
'article_tag#article_id': 12,
'article_tag#tag_id': 5,
'tag#id': 5,
'tag#name': 'Decorating',
'tag#slug': 'decorating'
}, {
'article#id': 12,
'article#author_id': 17,
'article#created_date': new Date('2018-02-14T19:09:29.628Z'),
'article#read_time_minutes': 5,
'article#seo_description': 'The real reasons',
'article#primary_image': 'https://example.com/e64284f2d0.jpg',
'article#title': '6 Surprising Reasons Why Homeowners Really Work On Their Lawn & Garden',
'article#slug': '6-surprising-reasons-why-homeowners-really-work-on-their-lawn-and-garden',
'article#body': '<p>Why?</p>',
'article#amp_body': '<p>Why?</p>',
'article#kind': 'BlogPosting',
'article#points': 11,
'person#id': 17,
'person#first_name': 'David',
'person#last_name': 'Swift',
'person#slug': 'david-swift',
'person#email': 'swift@swift.com',
'person#picture': 'https://example.com/swift.jpg',
'person#cover_photo': 'https://example.com/cover.jpg',
'person#brand': 'David Swift',
'person#tagline': 'My milkweed brings all the gnomes to the yard',
'person#display_name': 'David Swift',
'person#biography': 'With a garden trowel in one hand',
'person#title': 'Official Blogger',
'article_tag#id': 35,
'article_tag#article_id': 12,
'article_tag#tag_id': 15,
'tag#id': 15,
'tag#name': 'Foo',
'tag#slug': 'foo'
}];
const articles = Article.createFromDatabase(results);
expect(Array.isArray(articles.models)).toBe(true);
expect(articles instanceof Articles).toBe(true);
expect(articles.models.length).toEqual(2);
const first = articles.models[0];
expect(first.person.id).toEqual(8);
expect(first.articleTags.models.length).toEqual(10);
expect(first.articleTags.models[0].id).toEqual(36);
expect(first.articleTags.models[0].tag.id).toEqual(3);
expect(first.articleTags.models[1].id).toEqual(37);
expect(first.articleTags.models[1].tag.id).toEqual(4);
expect(first.articleTags.models[2].id).toEqual(38);
expect(first.articleTags.models[2].tag.id).toEqual(5);
expect(first.articleTags.models[3].id).toEqual(39);
expect(first.articleTags.models[3].tag.id).toEqual(6);
expect(first.articleTags.models[4].id).toEqual(40);
expect(first.articleTags.models[4].tag.id).toEqual(7);
expect(first.articleTags.models[5].id).toEqual(41);
expect(first.articleTags.models[5].tag.id).toEqual(8);
expect(first.articleTags.models[6].id).toEqual(42);
expect(first.articleTags.models[6].tag.id).toEqual(9);
expect(first.articleTags.models[7].id).toEqual(43);
expect(first.articleTags.models[7].tag.id).toEqual(11);
expect(first.articleTags.models[8].id).toEqual(44);
expect(first.articleTags.models[8].tag.id).toEqual(12);
expect(first.articleTags.models[9].id).toEqual(45);
expect(first.articleTags.models[9].tag.id).toEqual(16);
const second = articles.models[1];
expect(second.id).toEqual(12);
expect(second.person.id).toEqual(17);
expect(second.articleTags.models.length).toEqual(3);
expect(second.articleTags.models[0].id).toEqual(33);
expect(second.articleTags.models[0].tag.id).toEqual(1);
expect(second.articleTags.models[1].id).toEqual(34);
expect(second.articleTags.models[1].tag.id).toEqual(5);
expect(second.articleTags.models[2].id).toEqual(35);
expect(second.articleTags.models[2].tag.id).toEqual(15);
});