UNPKG

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
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); });