|
1 |
| -import { Rels } from '@foxy.io/sdk/backend'; |
2 |
| -import { Resource } from '@foxy.io/sdk/core'; |
| 1 | +import type { InternalNumberControl } from '../../internal/InternalNumberControl'; |
| 2 | +import type { FetchEvent } from '../NucleonElement/FetchEvent'; |
| 3 | +import type { Resource } from '@foxy.io/sdk/core'; |
| 4 | +import type { Rels } from '@foxy.io/sdk/backend'; |
| 5 | + |
| 6 | +import './index'; |
| 7 | + |
3 | 8 | import { expect, fixture, html, waitUntil } from '@open-wc/testing';
|
4 |
| -import { LitElement } from 'lit-element'; |
5 |
| -import { createRouter } from '../../../server/index'; |
6 |
| -import { getByKey } from '../../../testgen/getByKey'; |
7 |
| -import { getByTestId } from '../../../testgen/getByTestId'; |
8 |
| -import { getTestData } from '../../../testgen/getTestData'; |
9 |
| -import { FetchEvent } from '../NucleonElement/FetchEvent'; |
10 | 9 | import { NucleonElement } from '../NucleonElement/NucleonElement';
|
11 |
| -import { Pagination } from './index'; |
| 10 | +import { getByTestClass } from '../../../testgen/getByTestClass'; |
| 11 | +import { createRouter } from '../../../server/index'; |
| 12 | +import { Pagination } from './Pagination'; |
| 13 | +import { LitElement } from 'lit-element'; |
12 | 14 |
|
13 | 15 | type TestData = Resource<Rels.CouponCodes>;
|
14 | 16 | customElements.define('test-page-element', class extends NucleonElement<TestData> {});
|
@@ -46,159 +48,155 @@ describe('Pagination', () => {
|
46 | 48 | );
|
47 | 49 | });
|
48 | 50 |
|
49 |
| - (['next', 'last', 'prev', 'first'] as const).forEach(rel => { |
50 |
| - it(`sets "${rel}" URL as "href" on the page element when "${rel}" button is clicked`, async () => { |
51 |
| - const router = createRouter(); |
52 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
53 |
| - const element = await fixture(html` |
54 |
| - <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=1&offset=2"> |
55 |
| - <test-page-element @fetch=${handle}></test-page-element> |
56 |
| - </foxy-pagination> |
57 |
| - `); |
58 |
| - |
59 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
60 |
| - await waitUntil(() => page.in({ idle: 'snapshot' })); |
61 |
| - |
62 |
| - const newHref = page.data?._links[rel].href; |
63 |
| - const button = await getByTestId(element, rel); |
64 |
| - button?.click(); |
65 |
| - |
66 |
| - expect(page).to.have.property('href', newHref); |
67 |
| - }); |
68 |
| - }); |
69 |
| - |
70 |
| - it('disables "prev" and "first" buttons on first page', async () => { |
| 51 | + it('renders limit selector', async () => { |
71 | 52 | const router = createRouter();
|
72 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
73 |
| - const element = await fixture(html` |
74 |
| - <foxy-pagination first="https://demo.api/hapi/coupon_codes"> |
75 |
| - <test-page-element @fetch=${handle}></test-page-element> |
| 53 | + const element = await fixture<Pagination>(html` |
| 54 | + <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=3"> |
| 55 | + <test-page-element @fetch=${(evt: FetchEvent) => router.handleEvent(evt)}> |
| 56 | + </test-page-element> |
76 | 57 | </foxy-pagination>
|
77 | 58 | `);
|
78 | 59 |
|
79 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
80 |
| - await waitUntil(() => page.in({ idle: 'snapshot' })); |
81 |
| - |
82 |
| - expect(await getByTestId(element, 'first')).to.have.attribute('disabled'); |
83 |
| - expect(await getByTestId(element, 'prev')).to.have.attribute('disabled'); |
| 60 | + const pageElement = element.firstElementChild as NucleonElement<TestData>; |
| 61 | + await waitUntil(() => pageElement.in('idle')); |
| 62 | + |
| 63 | + const labelI18n = element.renderRoot.querySelector('foxy-i18n[infer=""][key="per_page"]'); |
| 64 | + const label = labelI18n?.closest('label'); |
| 65 | + const select = label?.htmlFor |
| 66 | + ? element.renderRoot.querySelector<HTMLSelectElement>(`#${label.htmlFor}`) |
| 67 | + : null; |
| 68 | + |
| 69 | + expect(select).to.exist; |
| 70 | + expect(select?.options.item(0)).to.have.property('value', '3'); |
| 71 | + expect(select?.options.item(1)).to.have.property('value', '20'); |
| 72 | + expect(select?.options.item(2)).to.have.property('value', '50'); |
| 73 | + expect(select?.options.item(3)).to.have.property('value', '100'); |
| 74 | + expect(select?.options.item(4)).to.have.property('value', '150'); |
| 75 | + expect(select?.options.item(5)).to.have.property('value', '200'); |
| 76 | + expect(select?.options.item(6)).to.not.exist; |
| 77 | + |
| 78 | + select!.value = '20'; |
| 79 | + select!.dispatchEvent(new Event('change')); |
| 80 | + await element.requestUpdate('__page'); |
| 81 | + expect(pageElement.href).to.equal('https://demo.api/hapi/coupon_codes?limit=20'); |
84 | 82 | });
|
85 | 83 |
|
86 |
| - it('disables "last" and "next" buttons on last page', async () => { |
| 84 | + it('renders simple pagination', async () => { |
87 | 85 | const router = createRouter();
|
88 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
89 |
| - const data = await getTestData<TestData>('./hapi/coupon_codes'); |
90 |
| - |
91 |
| - const element = await fixture(html` |
92 |
| - <foxy-pagination first=${data._links.last.href}> |
93 |
| - <test-page-element @fetch=${handle}></test-page-element> |
| 86 | + const element = await fixture<Pagination>(html` |
| 87 | + <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=50"> |
| 88 | + <test-page-element @fetch=${(evt: FetchEvent) => router.handleEvent(evt)}> |
| 89 | + </test-page-element> |
94 | 90 | </foxy-pagination>
|
95 | 91 | `);
|
96 | 92 |
|
97 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
98 |
| - await waitUntil(() => page.in({ idle: 'snapshot' })); |
| 93 | + const pageElement = element.firstElementChild as NucleonElement<TestData>; |
| 94 | + await waitUntil(() => pageElement.in('idle')); |
99 | 95 |
|
100 |
| - expect(await getByTestId(element, 'last')).to.have.attribute('disabled'); |
101 |
| - expect(await getByTestId(element, 'next')).to.have.attribute('disabled'); |
102 |
| - }); |
103 |
| - |
104 |
| - it('hides all buttons while loading', async () => { |
105 |
| - const router = createRouter(); |
106 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
107 |
| - const element = await fixture(html` |
108 |
| - <foxy-pagination first="https://demo.api/virtual/stall"> |
109 |
| - <test-page-element @fetch=${handle}></test-page-element> |
110 |
| - </foxy-pagination> |
111 |
| - `); |
| 96 | + const jumpToLabel = element.renderRoot.querySelector('foxy-i18n[infer=""][key="jump_to"]'); |
| 97 | + expect(jumpToLabel).to.exist; |
112 | 98 |
|
113 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
114 |
| - await waitUntil(() => page.in('busy')); |
| 99 | + const buttons = await getByTestClass(element, 'page-link'); |
| 100 | + expect(buttons).to.have.length(2); |
| 101 | + expect(buttons[0].textContent?.trim()).to.equal('1'); |
| 102 | + expect(buttons[0]).to.have.attribute('disabled'); |
| 103 | + expect(buttons[1].textContent?.trim()).to.equal('2'); |
| 104 | + expect(buttons[1]).to.not.have.attribute('disabled'); |
115 | 105 |
|
116 |
| - expect(await getByTestId(element, 'first')).to.not.exist; |
117 |
| - expect(await getByTestId(element, 'prev')).to.not.exist; |
118 |
| - expect(await getByTestId(element, 'last')).to.not.exist; |
119 |
| - expect(await getByTestId(element, 'next')).to.not.exist; |
| 106 | + buttons[1].click(); |
| 107 | + await element.requestUpdate('__page'); |
| 108 | + expect(pageElement.href).to.equal('https://demo.api/hapi/coupon_codes?limit=50&offset=50'); |
| 109 | + expect(buttons[0]).to.not.have.attribute('disabled'); |
| 110 | + expect(buttons[1]).to.have.attribute('disabled'); |
120 | 111 | });
|
121 | 112 |
|
122 |
| - it('hides all buttons if collection length is less than limit', async () => { |
| 113 | + it('renders complex pagination with overflow', async () => { |
123 | 114 | const router = createRouter();
|
124 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
125 |
| - const element = await fixture(html` |
126 |
| - <foxy-pagination first="https://demo.api/hapi/transactions"> |
127 |
| - <test-page-element @fetch=${handle}></test-page-element> |
| 115 | + const element = await fixture<Pagination>(html` |
| 116 | + <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=10"> |
| 117 | + <test-page-element @fetch=${(evt: FetchEvent) => router.handleEvent(evt)}> |
| 118 | + </test-page-element> |
128 | 119 | </foxy-pagination>
|
129 | 120 | `);
|
130 | 121 |
|
131 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
132 |
| - await waitUntil(() => page.in('idle')); |
| 122 | + const pageElement = element.firstElementChild as NucleonElement<TestData>; |
| 123 | + await waitUntil(() => pageElement.in('idle')); |
133 | 124 |
|
134 |
| - expect(await getByTestId(element, 'first')).to.not.exist; |
135 |
| - expect(await getByTestId(element, 'prev')).to.not.exist; |
136 |
| - expect(await getByTestId(element, 'last')).to.not.exist; |
137 |
| - expect(await getByTestId(element, 'next')).to.not.exist; |
138 |
| - }); |
| 125 | + const buttons = await getByTestClass(element, 'page-link'); |
| 126 | + expect(buttons).to.have.length(7); |
| 127 | + expect(buttons[0].textContent?.trim()).to.equal('1'); |
| 128 | + expect(buttons[1].textContent?.trim()).to.equal('2'); |
| 129 | + expect(buttons[2].textContent?.trim()).to.equal('3'); |
| 130 | + expect(buttons[3].textContent?.trim()).to.equal('4'); |
| 131 | + expect(buttons[4].textContent?.trim()).to.equal('5'); |
| 132 | + expect(buttons[5].textContent?.trim()).to.equal('...'); |
| 133 | + expect(buttons[6].textContent?.trim()).to.equal('10'); |
139 | 134 |
|
140 |
| - it('disables all buttons when disabled is true', async () => { |
141 |
| - const router = createRouter(); |
142 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
143 |
| - const element = await fixture(html` |
144 |
| - <foxy-pagination first="https://demo.api/hapi/coupon_codes" disabled> |
145 |
| - <test-page-element @fetch=${handle}></test-page-element> |
146 |
| - </foxy-pagination> |
147 |
| - `); |
| 135 | + const dialog = element.renderRoot.querySelector('dialog'); |
| 136 | + expect(dialog).to.not.have.attribute('open'); |
148 | 137 |
|
149 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
150 |
| - await waitUntil(() => page.in({ idle: 'snapshot' })); |
151 |
| - |
152 |
| - expect(await getByTestId(element, 'first')).to.have.attribute('disabled'); |
153 |
| - expect(await getByTestId(element, 'prev')).to.have.attribute('disabled'); |
154 |
| - expect(await getByTestId(element, 'last')).to.have.attribute('disabled'); |
155 |
| - expect(await getByTestId(element, 'next')).to.have.attribute('disabled'); |
| 138 | + buttons[5].click(); |
| 139 | + expect(dialog).to.have.attribute('open'); |
156 | 140 | });
|
157 | 141 |
|
158 |
| - it('enables all buttons when navigation is available in any direction', async () => { |
| 142 | + it('renders Jump To dialog', async () => { |
159 | 143 | const router = createRouter();
|
160 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
161 |
| - const element = await fixture(html` |
162 |
| - <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=1&offset=2"> |
163 |
| - <test-page-element @fetch=${handle}></test-page-element> |
| 144 | + const element = await fixture<Pagination>(html` |
| 145 | + <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=10"> |
| 146 | + <test-page-element @fetch=${(evt: FetchEvent) => router.handleEvent(evt)}> |
| 147 | + </test-page-element> |
164 | 148 | </foxy-pagination>
|
165 | 149 | `);
|
166 | 150 |
|
167 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
168 |
| - await waitUntil(() => page.in({ idle: 'snapshot' })); |
169 |
| - |
170 |
| - expect(await getByTestId(element, 'first')).to.not.have.attribute('disabled'); |
171 |
| - expect(await getByTestId(element, 'prev')).to.not.have.attribute('disabled'); |
172 |
| - expect(await getByTestId(element, 'last')).to.not.have.attribute('disabled'); |
173 |
| - expect(await getByTestId(element, 'next')).to.not.have.attribute('disabled'); |
| 151 | + const pageElement = element.firstElementChild as NucleonElement<TestData>; |
| 152 | + await waitUntil(() => pageElement.in('idle')); |
| 153 | + const dialog = element.renderRoot.querySelector('dialog'); |
| 154 | + const input = dialog?.querySelector<InternalNumberControl>('foxy-internal-number-control'); |
| 155 | + |
| 156 | + expect(input).to.exist; |
| 157 | + expect(input).to.have.attribute('placeholder', '1'); |
| 158 | + expect(input).to.have.attribute('helper-text', ''); |
| 159 | + expect(input).to.have.attribute('label', 'page_number'); |
| 160 | + expect(input).to.have.attribute('infer', ''); |
| 161 | + expect(input).to.have.attribute('step', '1'); |
| 162 | + expect(input).to.have.attribute('min', '1'); |
| 163 | + expect(input).to.have.attribute('max', '10'); |
| 164 | + expect(input?.getValue()).to.equal(1); |
| 165 | + |
| 166 | + dialog?.showModal(); |
| 167 | + input?.setValue(7); |
| 168 | + input?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' })); |
| 169 | + await element.requestUpdate('__page'); |
| 170 | + expect(pageElement.href).to.equal('https://demo.api/hapi/coupon_codes?limit=10&offset=60'); |
| 171 | + expect(dialog).to.not.have.attribute('open'); |
| 172 | + |
| 173 | + dialog?.showModal(); |
| 174 | + input?.setValue(8); |
| 175 | + const jumpLabel = element.renderRoot.querySelector('foxy-i18n[infer=""][key="jump"]'); |
| 176 | + const jumpButton = jumpLabel?.closest('vaadin-button'); |
| 177 | + jumpButton?.click(); |
| 178 | + await element.requestUpdate('__page'); |
| 179 | + expect(pageElement.href).to.equal('https://demo.api/hapi/coupon_codes?limit=10&offset=70'); |
| 180 | + expect(dialog).to.not.have.attribute('open'); |
174 | 181 | });
|
175 | 182 |
|
176 |
| - it('renders current page in a label', async () => { |
| 183 | + it('disables controls when disabled', async () => { |
177 | 184 | const router = createRouter();
|
178 |
| - const handle = (evt: FetchEvent) => router.handleEvent(evt); |
179 |
| - const element = await fixture(html` |
180 |
| - <foxy-pagination |
181 |
| - first="https://demo.api/hapi/coupon_codes?limit=2&offset=2" |
182 |
| - lang="es" |
183 |
| - ns="foo" |
184 |
| - > |
185 |
| - <test-page-element @fetch=${handle}></test-page-element> |
| 185 | + const element = await fixture<Pagination>(html` |
| 186 | + <foxy-pagination first="https://demo.api/hapi/coupon_codes?limit=50" disabled> |
| 187 | + <test-page-element @fetch=${(evt: FetchEvent) => router.handleEvent(evt)}> |
| 188 | + </test-page-element> |
186 | 189 | </foxy-pagination>
|
187 | 190 | `);
|
188 | 191 |
|
189 |
| - const page = element.firstElementChild as NucleonElement<TestData>; |
190 |
| - await waitUntil(() => page.in({ idle: 'snapshot' })); |
191 |
| - const label = await getByKey(element, 'pagination'); |
192 |
| - |
193 |
| - expect(label).to.have.attribute('ns', 'foo'); |
194 |
| - expect(label).to.have.attribute('lang', 'es'); |
195 |
| - expect(label).to.have.attribute( |
196 |
| - 'options', |
197 |
| - JSON.stringify({ |
198 |
| - total: page.data?.total_items, |
199 |
| - from: 3, |
200 |
| - to: 4, |
201 |
| - }) |
202 |
| - ); |
| 192 | + const pageElement = element.firstElementChild as NucleonElement<TestData>; |
| 193 | + await waitUntil(() => pageElement.in('idle')); |
| 194 | + |
| 195 | + const buttons = await getByTestClass(element, 'page-link'); |
| 196 | + const select = element.renderRoot.querySelector<HTMLSelectElement>('select'); |
| 197 | + |
| 198 | + expect(buttons[0]).to.have.attribute('disabled'); |
| 199 | + expect(buttons[1]).to.have.attribute('disabled'); |
| 200 | + expect(select).to.have.attribute('disabled'); |
203 | 201 | });
|
204 | 202 | });
|
0 commit comments