@block-auth.io/angular 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +7 -7
- package/.turbo/turbo-lint.log +4 -4
- package/.turbo/turbo-test.log +1216 -82
- package/.turbo/turbo-typecheck.log +19 -4
- package/CHANGELOG.md +13 -0
- package/package.json +2 -2
- package/src/lib/components/dds/dropdown-profile-btn.component.ts +13 -28
- package/src/lib/components/dds/dropdown-profile.component.test.ts +14 -2
- package/src/lib/components/dds/dropdown-profile.component.ts +25 -19
- package/src/lib/components/txns/internals/permissions-required-modal.component.test.ts +16 -3
- package/src/lib/components/txns/internals/permissions-required-modal.component.ts +24 -16
- package/src/lib/components/txns/internals/solicited-data-modal.component.test.ts +37 -5
- package/src/lib/components/txns/internals/solicited-data-modal.component.ts +98 -65
- package/src/lib/components/txns/internals/txn-error.component.test.ts +33 -6
- package/src/lib/components/txns/internals/txn-error.component.ts +52 -29
- package/src/lib/components/txns/internals/txn.component.test.ts +63 -16
- package/src/lib/components/txns/internals/txn.component.ts +141 -61
- package/src/lib/components/txns/txns-overview.component.ts +109 -91
|
@@ -1,16 +1,22 @@
|
|
|
1
1
|
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
2
|
import { Component } from '@angular/core';
|
|
3
3
|
import { render, screen, fireEvent } from '@testing-library/angular';
|
|
4
|
+
import { setLocale } from '@block-auth.io/core';
|
|
4
5
|
import { TxnErrorComponent } from './txn-error.component';
|
|
5
6
|
import { provideBlockAuthClientForTest } from '../../../testing';
|
|
6
7
|
|
|
7
8
|
vi.mock('@wagmi/core', () => ({
|
|
8
9
|
createConfig: vi.fn(() => ({ connectors: [] })),
|
|
9
|
-
connect: vi.fn(),
|
|
10
|
-
|
|
10
|
+
connect: vi.fn(),
|
|
11
|
+
disconnect: vi.fn(),
|
|
12
|
+
getAccount: vi.fn(() => ({})),
|
|
13
|
+
signMessage: vi.fn(),
|
|
14
|
+
watchAccount: vi.fn(() => () => undefined),
|
|
15
|
+
http: vi.fn(),
|
|
11
16
|
}));
|
|
12
17
|
vi.mock('@wagmi/connectors', () => ({
|
|
13
|
-
injected: vi.fn(() => ({ id: 'injected' })),
|
|
18
|
+
injected: vi.fn(() => ({ id: 'injected' })),
|
|
19
|
+
walletConnect: vi.fn(() => ({ id: 'walletConnect' })),
|
|
14
20
|
}));
|
|
15
21
|
|
|
16
22
|
// Port de packages/react/src/components/txns/internals/TxnError.test.tsx +
|
|
@@ -20,6 +26,8 @@ describe('TxnError', () => {
|
|
|
20
26
|
return { txns: { report } } as any;
|
|
21
27
|
}
|
|
22
28
|
|
|
29
|
+
afterEach(() => setLocale('en'));
|
|
30
|
+
|
|
23
31
|
it('renderiza el panel de error de txn', async () => {
|
|
24
32
|
await render(TxnErrorComponent, {
|
|
25
33
|
inputs: { errorMessageTxt: 'No transactions found' },
|
|
@@ -29,10 +37,22 @@ describe('TxnError', () => {
|
|
|
29
37
|
expect(screen.getByText('REPORT')).toBeDefined();
|
|
30
38
|
});
|
|
31
39
|
|
|
40
|
+
it('respeta el locale activo cuando no se pasan textos custom', async () => {
|
|
41
|
+
setLocale('es');
|
|
42
|
+
await render(TxnErrorComponent, {
|
|
43
|
+
inputs: { errorMessageTxt: 'No transactions found' },
|
|
44
|
+
providers: [provideBlockAuthClientForTest(makeClient())],
|
|
45
|
+
});
|
|
46
|
+
expect(screen.getByText('REPORTAR')).toBeDefined();
|
|
47
|
+
});
|
|
48
|
+
|
|
32
49
|
it('REPORT llama a client.txns.report(slug)', async () => {
|
|
33
50
|
const report = vi.fn();
|
|
34
51
|
await render(TxnErrorComponent, {
|
|
35
|
-
inputs: {
|
|
52
|
+
inputs: {
|
|
53
|
+
errorMessageTxt: 'No transactions found',
|
|
54
|
+
errorMessageSlug: 'no_transactions_found',
|
|
55
|
+
},
|
|
36
56
|
providers: [provideBlockAuthClientForTest(makeClient(report))],
|
|
37
57
|
});
|
|
38
58
|
await fireEvent.click(screen.getByText('REPORT'));
|
|
@@ -52,7 +72,10 @@ describe('TxnError', () => {
|
|
|
52
72
|
@Component({
|
|
53
73
|
standalone: true,
|
|
54
74
|
imports: [TxnErrorComponent],
|
|
55
|
-
template: `<ba-txn-error
|
|
75
|
+
template: `<ba-txn-error
|
|
76
|
+
errorMessageTxt="No transactions found"
|
|
77
|
+
[closeTxns]="c"
|
|
78
|
+
/>`,
|
|
56
79
|
})
|
|
57
80
|
class Host {
|
|
58
81
|
c = closeTxns;
|
|
@@ -78,7 +101,11 @@ describe('TxnError', () => {
|
|
|
78
101
|
@Component({
|
|
79
102
|
standalone: true,
|
|
80
103
|
imports: [TxnErrorComponent],
|
|
81
|
-
template: `<ba-txn-error
|
|
104
|
+
template: `<ba-txn-error
|
|
105
|
+
errorMessageTxt="No transactions found"
|
|
106
|
+
[closeTxns]="c"
|
|
107
|
+
[isCountdown]="false"
|
|
108
|
+
/>`,
|
|
82
109
|
})
|
|
83
110
|
class Host {
|
|
84
111
|
c = closeTxns;
|
|
@@ -2,10 +2,13 @@ import {
|
|
|
2
2
|
ChangeDetectionStrategy,
|
|
3
3
|
Component,
|
|
4
4
|
DestroyRef,
|
|
5
|
+
computed,
|
|
5
6
|
inject,
|
|
6
7
|
input,
|
|
7
8
|
signal,
|
|
8
9
|
} from '@angular/core';
|
|
10
|
+
import { $locale, t as translate, type TextKey } from '@block-auth.io/core';
|
|
11
|
+
import { injectStore } from '../../../inject-store';
|
|
9
12
|
import { injectBlockAuthClient } from '../../../provide-block-auth';
|
|
10
13
|
|
|
11
14
|
// `closeTxns` se mantiene como INPUT DE FUNCIÓN (no output): react lo invoca
|
|
@@ -31,40 +34,42 @@ import { injectBlockAuthClient } from '../../../provide-block-auth';
|
|
|
31
34
|
>
|
|
32
35
|
<p class="bas-m-0">{{ errorMessageTxt() }}</p>
|
|
33
36
|
</div>
|
|
34
|
-
<div
|
|
37
|
+
<div
|
|
38
|
+
class="bas-box-border bas-flex bas-w-full bas-flex-col bas-items-center bas-justify-center bas-gap-1 bas-px-1"
|
|
39
|
+
>
|
|
35
40
|
<div class="bas-h-16 bas-w-full">
|
|
36
41
|
@if (!reportSent()) {
|
|
37
|
-
|
|
42
|
+
<p class="bas-m-0">{{ helpUsTxtResolved() }}</p>
|
|
38
43
|
} @else {
|
|
39
|
-
|
|
44
|
+
<p class="bas-m-0">{{ thanksForReportTxtResolved() }}</p>
|
|
40
45
|
}
|
|
41
46
|
</div>
|
|
42
47
|
@if (!reportSent()) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
<button
|
|
49
|
+
type="button"
|
|
50
|
+
id="btn-txn-report-error"
|
|
51
|
+
[disabled]="sendingReport()"
|
|
52
|
+
class="bal-ba-hover-ring-red-500 bal-ba-focus-ring-red-500 bas-mt-2 bas-w-[220px] bas-justify-center bas-bg-red-500 hover:bas-bg-red-600 bas-px-4 bas-text-center bas-text-xl bas-font-medium bas-text-[var(--bal-primary-10)]"
|
|
53
|
+
(click)="onReportErrorClicked()"
|
|
54
|
+
>
|
|
55
|
+
{{ sendingReport() ? '…' : reportTxtResolved() }}
|
|
56
|
+
</button>
|
|
52
57
|
} @else {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
<button
|
|
59
|
+
type="button"
|
|
60
|
+
id="btn-txn-error-report"
|
|
61
|
+
class="bal-ba-hover-ring-primary-300 bal-ba-focus-ring-primary-300 bas-mt-2 bas-w-[220px] bas-justify-center bas-rounded-md bas-border-2 bas-border-solid bas-border-[var(--bal-primary-300)] bas-bg-transparent bas-px-4 bas-text-center bas-text-xl bas-font-medium bas-text-[var(--bal-primary-700)] group-hover:bas-text-[var(--bal-primary-900)]"
|
|
62
|
+
(click)="close()"
|
|
63
|
+
>
|
|
64
|
+
{{ textCloseTxtResolved() }}
|
|
65
|
+
</button>
|
|
61
66
|
}
|
|
62
67
|
</div>
|
|
63
68
|
@if (reportSent() && isCountdown()) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
69
|
+
<div class="bas-flex bas-flex-row bas-items-end bas-gap-2">
|
|
70
|
+
<p class="bas-m-0">{{ modalWillCloseInTxtResolved() }}</p>
|
|
71
|
+
<p class="bas-m-0">{{ countDown() }}</p>
|
|
72
|
+
</div>
|
|
68
73
|
}
|
|
69
74
|
</div>
|
|
70
75
|
`,
|
|
@@ -73,14 +78,32 @@ export class TxnErrorComponent {
|
|
|
73
78
|
errorMessageSlug = input('unknown');
|
|
74
79
|
errorMessageTxt = input('unknown');
|
|
75
80
|
closeTxns = input<() => void>(() => {});
|
|
76
|
-
helpUsTxt = input(
|
|
77
|
-
thanksForReportTxt = input(
|
|
78
|
-
reportTxt = input(
|
|
79
|
-
textCloseTxt = input(
|
|
80
|
-
modalWillCloseInTxt = input(
|
|
81
|
+
helpUsTxt = input<string>();
|
|
82
|
+
thanksForReportTxt = input<string>();
|
|
83
|
+
reportTxt = input<string>();
|
|
84
|
+
textCloseTxt = input<string>();
|
|
85
|
+
modalWillCloseInTxt = input<string>();
|
|
81
86
|
isCountdown = input(true);
|
|
82
87
|
|
|
83
88
|
private readonly client = injectBlockAuthClient();
|
|
89
|
+
private readonly locale = injectStore($locale);
|
|
90
|
+
protected t = (key: TextKey): string => translate(key, this.locale());
|
|
91
|
+
|
|
92
|
+
protected readonly helpUsTxtResolved = computed(
|
|
93
|
+
() => this.helpUsTxt() ?? this.t('helpUsReport'),
|
|
94
|
+
);
|
|
95
|
+
protected readonly thanksForReportTxtResolved = computed(
|
|
96
|
+
() => this.thanksForReportTxt() ?? this.t('thanksForReport'),
|
|
97
|
+
);
|
|
98
|
+
protected readonly reportTxtResolved = computed(
|
|
99
|
+
() => this.reportTxt() ?? this.t('report'),
|
|
100
|
+
);
|
|
101
|
+
protected readonly textCloseTxtResolved = computed(
|
|
102
|
+
() => this.textCloseTxt() ?? this.t('close'),
|
|
103
|
+
);
|
|
104
|
+
protected readonly modalWillCloseInTxtResolved = computed(
|
|
105
|
+
() => this.modalWillCloseInTxt() ?? this.t('modalWillCloseIn'),
|
|
106
|
+
);
|
|
84
107
|
|
|
85
108
|
protected readonly sendingReport = signal(false);
|
|
86
109
|
protected readonly reportSent = signal(false);
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
1
|
+
import { describe, it, expect, vi, afterEach } from 'vitest';
|
|
2
2
|
import { Component } from '@angular/core';
|
|
3
3
|
import { render, screen, fireEvent } from '@testing-library/angular';
|
|
4
4
|
import { map } from 'nanostores';
|
|
5
|
+
import { setLocale } from '@block-auth.io/core';
|
|
5
6
|
import { TxnComponent } from './txn.component';
|
|
6
7
|
import { provideBlockAuthClientForTest } from '../../../testing';
|
|
7
8
|
|
|
8
9
|
vi.mock('@wagmi/core', () => ({
|
|
9
10
|
createConfig: vi.fn(() => ({ connectors: [] })),
|
|
10
|
-
connect: vi.fn(),
|
|
11
|
-
|
|
11
|
+
connect: vi.fn(),
|
|
12
|
+
disconnect: vi.fn(),
|
|
13
|
+
getAccount: vi.fn(() => ({})),
|
|
14
|
+
signMessage: vi.fn(),
|
|
15
|
+
watchAccount: vi.fn(() => () => undefined),
|
|
16
|
+
http: vi.fn(),
|
|
12
17
|
}));
|
|
13
18
|
vi.mock('@wagmi/connectors', () => ({
|
|
14
|
-
injected: vi.fn(() => ({ id: 'injected' })),
|
|
19
|
+
injected: vi.fn(() => ({ id: 'injected' })),
|
|
20
|
+
walletConnect: vi.fn(() => ({ id: 'walletConnect' })),
|
|
15
21
|
}));
|
|
16
22
|
|
|
17
23
|
// Port de packages/react/src/components/txns/internals/Txn.test.tsx +
|
|
@@ -30,6 +36,8 @@ describe('Txn', () => {
|
|
|
30
36
|
} as any;
|
|
31
37
|
}
|
|
32
38
|
|
|
39
|
+
afterEach(() => setLocale('en'));
|
|
40
|
+
|
|
33
41
|
it('renderiza el cuerpo de la txn con aceptar/rechazar', async () => {
|
|
34
42
|
await render(TxnComponent, {
|
|
35
43
|
inputs: { hasSolicitedData: true },
|
|
@@ -40,10 +48,27 @@ describe('Txn', () => {
|
|
|
40
48
|
expect(screen.getByText('REJECT')).toBeDefined();
|
|
41
49
|
});
|
|
42
50
|
|
|
51
|
+
it('respeta el locale activo cuando no se pasan textos custom', async () => {
|
|
52
|
+
setLocale('es');
|
|
53
|
+
await render(TxnComponent, {
|
|
54
|
+
inputs: { hasSolicitedData: true },
|
|
55
|
+
providers: [provideBlockAuthClientForTest(makeClient())],
|
|
56
|
+
});
|
|
57
|
+
expect(screen.getByText('Permisos requeridos')).toBeDefined();
|
|
58
|
+
expect(screen.getByText('ACEPTAR')).toBeDefined();
|
|
59
|
+
expect(screen.getByText('RECHAZAR')).toBeDefined();
|
|
60
|
+
});
|
|
61
|
+
|
|
43
62
|
it('ACCEPT esta deshabilitado hasta aceptar PPTC (y allRequiredFilled)', async () => {
|
|
44
|
-
await render(TxnComponent, {
|
|
45
|
-
|
|
46
|
-
|
|
63
|
+
await render(TxnComponent, {
|
|
64
|
+
providers: [provideBlockAuthClientForTest(makeClient())],
|
|
65
|
+
});
|
|
66
|
+
const acceptBtn = screen
|
|
67
|
+
.getByText('ACCEPT')
|
|
68
|
+
.closest('button') as HTMLButtonElement;
|
|
69
|
+
const checkbox = screen.getByTestId(
|
|
70
|
+
'checkbox-animated',
|
|
71
|
+
) as HTMLInputElement;
|
|
47
72
|
expect(acceptBtn.disabled).toBe(true);
|
|
48
73
|
expect(checkbox.checked).toBe(false);
|
|
49
74
|
|
|
@@ -58,7 +83,9 @@ describe('Txn', () => {
|
|
|
58
83
|
providers: [provideBlockAuthClientForTest(makeClient())],
|
|
59
84
|
});
|
|
60
85
|
await fireEvent.click(screen.getByTestId('txn-pptc-toggle'));
|
|
61
|
-
const acceptBtn = screen
|
|
86
|
+
const acceptBtn = screen
|
|
87
|
+
.getByText('ACCEPT')
|
|
88
|
+
.closest('button') as HTMLButtonElement;
|
|
62
89
|
expect(acceptBtn.disabled).toBe(true);
|
|
63
90
|
});
|
|
64
91
|
|
|
@@ -105,7 +132,10 @@ describe('Txn', () => {
|
|
|
105
132
|
@Component({
|
|
106
133
|
standalone: true,
|
|
107
134
|
imports: [TxnComponent],
|
|
108
|
-
template: `<ba-txn
|
|
135
|
+
template: `<ba-txn
|
|
136
|
+
[selectedTxnPreParams]="{ appKey: 'k' }"
|
|
137
|
+
[addError]="e"
|
|
138
|
+
/>`,
|
|
109
139
|
})
|
|
110
140
|
class Host {
|
|
111
141
|
e = addError;
|
|
@@ -122,7 +152,10 @@ describe('Txn', () => {
|
|
|
122
152
|
@Component({
|
|
123
153
|
standalone: true,
|
|
124
154
|
imports: [TxnComponent],
|
|
125
|
-
template: `<ba-txn
|
|
155
|
+
template: `<ba-txn
|
|
156
|
+
[selectedTxnPreParams]="{ appKey: 'k', to: '0xabc' }"
|
|
157
|
+
[userParamValues]="{ 'users-email': 'a@b.com' }"
|
|
158
|
+
/>`,
|
|
126
159
|
})
|
|
127
160
|
class Host {}
|
|
128
161
|
await render(Host, { providers: [provideBlockAuthClientForTest(client)] });
|
|
@@ -141,13 +174,19 @@ describe('Txn', () => {
|
|
|
141
174
|
@Component({
|
|
142
175
|
standalone: true,
|
|
143
176
|
imports: [TxnComponent],
|
|
144
|
-
template: `<ba-txn
|
|
177
|
+
template: `<ba-txn
|
|
178
|
+
[hasSolicitedData]="true"
|
|
179
|
+
(permissionsRequiredClicked)="p()"
|
|
180
|
+
(solicitedDataClicked)="s()"
|
|
181
|
+
/>`,
|
|
145
182
|
})
|
|
146
183
|
class Host {
|
|
147
184
|
p = onPerm;
|
|
148
185
|
s = onSol;
|
|
149
186
|
}
|
|
150
|
-
await render(Host, {
|
|
187
|
+
await render(Host, {
|
|
188
|
+
providers: [provideBlockAuthClientForTest(makeClient())],
|
|
189
|
+
});
|
|
151
190
|
await fireEvent.click(screen.getByText('Permissions required'));
|
|
152
191
|
await fireEvent.click(screen.getByText('Solicited data'));
|
|
153
192
|
expect(onPerm).toHaveBeenCalledOnce();
|
|
@@ -160,9 +199,13 @@ describe('Txn', () => {
|
|
|
160
199
|
});
|
|
161
200
|
// Antes del click no hay ni slider ni TimePicker.
|
|
162
201
|
expect(container.querySelector('#txn-lifetime-slider-slider')).toBeNull();
|
|
163
|
-
await fireEvent.click(
|
|
202
|
+
await fireEvent.click(
|
|
203
|
+
screen.getByText('I want to configure my session time'),
|
|
204
|
+
);
|
|
164
205
|
// El slider estilado (SliderBase) y el input del TimePicker aparecen.
|
|
165
|
-
const slider = container.querySelector(
|
|
206
|
+
const slider = container.querySelector(
|
|
207
|
+
'#txn-lifetime-slider-slider',
|
|
208
|
+
) as HTMLInputElement;
|
|
166
209
|
expect(slider).not.toBeNull();
|
|
167
210
|
expect(slider.type).toBe('range');
|
|
168
211
|
const timeInput = container.querySelector(
|
|
@@ -177,8 +220,12 @@ describe('Txn', () => {
|
|
|
177
220
|
const { container } = await render(TxnComponent, {
|
|
178
221
|
providers: [provideBlockAuthClientForTest(makeClient())],
|
|
179
222
|
});
|
|
180
|
-
await fireEvent.click(
|
|
181
|
-
|
|
223
|
+
await fireEvent.click(
|
|
224
|
+
screen.getByText('I want to configure my session time'),
|
|
225
|
+
);
|
|
226
|
+
const slider = container.querySelector(
|
|
227
|
+
'#txn-lifetime-slider-slider',
|
|
228
|
+
) as HTMLInputElement;
|
|
182
229
|
await fireEvent.input(slider, { target: { value: '7200' } }); // 02:00:00
|
|
183
230
|
const timeInput = container.querySelector(
|
|
184
231
|
'#txn-lifetime-slider-time-picker-time-input',
|