@smess/networking 1.0.28 → 1.0.30

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.
Files changed (132) hide show
  1. package/dist/index.d.ts +6 -0
  2. package/dist/index.js +6 -0
  3. package/dist/services/customer.service.js +1 -1
  4. package/dist/services/storefront.cart.service.d.ts +73 -0
  5. package/dist/services/storefront.cart.service.js +167 -0
  6. package/dist/services/storefront.cart.service.test.d.ts +1 -0
  7. package/dist/services/storefront.cart.service.test.js +211 -0
  8. package/dist/services/storefront.checkout.service.d.ts +62 -0
  9. package/dist/services/storefront.checkout.service.js +75 -0
  10. package/dist/services/storefront.checkout.service.test.d.ts +1 -0
  11. package/dist/services/storefront.checkout.service.test.js +158 -0
  12. package/dist/services/storefront.customer.metadata.service.d.ts +91 -0
  13. package/dist/services/storefront.customer.metadata.service.js +225 -0
  14. package/dist/services/storefront.customer.metadata.service.test.d.ts +1 -0
  15. package/dist/services/storefront.customer.metadata.service.test.js +271 -0
  16. package/dist/services/storefront.order.service.d.ts +45 -0
  17. package/dist/services/storefront.order.service.js +99 -0
  18. package/dist/services/storefront.order.service.test.d.ts +1 -0
  19. package/dist/services/storefront.order.service.test.js +158 -0
  20. package/dist/services/storefront.product.service.d.ts +52 -0
  21. package/dist/services/storefront.product.service.js +75 -0
  22. package/dist/services/storefront.product.service.test.d.ts +1 -0
  23. package/dist/services/storefront.product.service.test.js +120 -0
  24. package/dist/services/storefront.store.service.d.ts +52 -0
  25. package/dist/services/storefront.store.service.js +140 -0
  26. package/dist/services/storefront.store.service.test.d.ts +1 -0
  27. package/dist/services/storefront.store.service.test.js +90 -0
  28. package/dist/src/core/axios.d.ts +51 -0
  29. package/dist/src/core/axios.js +65 -0
  30. package/dist/src/core/axios.observable.d.ts +11 -0
  31. package/dist/src/core/axios.observable.js +58 -0
  32. package/dist/src/core/base.provider.advanced.test.d.ts +1 -0
  33. package/dist/src/core/base.provider.advanced.test.js +29 -0
  34. package/dist/src/core/base.provider.d.ts +15 -0
  35. package/dist/src/core/base.provider.js +13 -0
  36. package/dist/src/core/base.provider.test.d.ts +1 -0
  37. package/dist/src/core/base.provider.test.js +36 -0
  38. package/dist/src/core/base.service.wrapper.advanced.test.d.ts +1 -0
  39. package/dist/src/core/base.service.wrapper.advanced.test.js +39 -0
  40. package/dist/src/core/base.service.wrapper.d.ts +7 -0
  41. package/dist/src/core/base.service.wrapper.js +11 -0
  42. package/dist/src/core/base.service.wrapper.test.d.ts +1 -0
  43. package/dist/src/core/base.service.wrapper.test.js +25 -0
  44. package/dist/src/core/rx.http.service.d.ts +51 -0
  45. package/dist/src/core/rx.http.service.js +65 -0
  46. package/dist/src/index.d.ts +25 -0
  47. package/dist/src/index.js +29 -0
  48. package/dist/src/services/auth.service.d.ts +65 -0
  49. package/dist/src/services/auth.service.js +197 -0
  50. package/dist/src/services/auth.service.test.d.ts +1 -0
  51. package/dist/src/services/auth.service.test.js +334 -0
  52. package/dist/src/services/cache.service.d.ts +31 -0
  53. package/dist/src/services/cache.service.js +77 -0
  54. package/dist/src/services/cache.service.test.d.ts +1 -0
  55. package/dist/src/services/cache.service.test.js +88 -0
  56. package/dist/src/services/customer.service.d.ts +199 -0
  57. package/dist/src/services/customer.service.js +114 -0
  58. package/dist/src/services/customer.service.test.d.ts +1 -0
  59. package/dist/src/services/customer.service.test.js +430 -0
  60. package/dist/src/services/employee.service.d.ts +73 -0
  61. package/dist/src/services/employee.service.js +74 -0
  62. package/dist/src/services/employee.service.test.d.ts +1 -0
  63. package/dist/src/services/employee.service.test.js +127 -0
  64. package/dist/src/services/logger.service.d.ts +31 -0
  65. package/dist/src/services/logger.service.js +93 -0
  66. package/dist/src/services/logger.service.test.d.ts +1 -0
  67. package/dist/src/services/logger.service.test.js +31 -0
  68. package/dist/src/services/order.service.d.ts +73 -0
  69. package/dist/src/services/order.service.js +97 -0
  70. package/dist/src/services/order.service.test.d.ts +1 -0
  71. package/dist/src/services/order.service.test.js +163 -0
  72. package/dist/src/services/product.service.d.ts +21 -0
  73. package/dist/src/services/product.service.js +42 -0
  74. package/dist/src/services/product.service.test.d.ts +1 -0
  75. package/dist/src/services/product.service.test.js +61 -0
  76. package/dist/src/services/smess.service.d.ts +36 -0
  77. package/dist/src/services/smess.service.js +128 -0
  78. package/dist/src/services/smess.service.test.d.ts +1 -0
  79. package/dist/src/services/smess.service.test.js +103 -0
  80. package/dist/src/services/store.cart.service.d.ts +158 -0
  81. package/dist/src/services/store.cart.service.js +177 -0
  82. package/dist/src/services/store.cart.service.test.d.ts +1 -0
  83. package/dist/src/services/store.cart.service.test.js +394 -0
  84. package/dist/src/services/store.product.service.d.ts +124 -0
  85. package/dist/src/services/store.product.service.js +102 -0
  86. package/dist/src/services/store.product.service.test.d.ts +1 -0
  87. package/dist/src/services/store.product.service.test.js +319 -0
  88. package/dist/src/services/store.service.d.ts +79 -0
  89. package/dist/src/services/store.service.js +235 -0
  90. package/dist/src/services/store.service.test.d.ts +1 -0
  91. package/dist/src/services/store.service.test.js +274 -0
  92. package/dist/src/services/storefront.cart.service.d.ts +73 -0
  93. package/dist/src/services/storefront.cart.service.js +167 -0
  94. package/dist/src/services/storefront.cart.service.test.d.ts +1 -0
  95. package/dist/src/services/storefront.cart.service.test.js +211 -0
  96. package/dist/src/services/storefront.checkout.service.d.ts +62 -0
  97. package/dist/src/services/storefront.checkout.service.js +75 -0
  98. package/dist/src/services/storefront.checkout.service.test.d.ts +1 -0
  99. package/dist/src/services/storefront.checkout.service.test.js +158 -0
  100. package/dist/src/services/storefront.customer.metadata.service.d.ts +91 -0
  101. package/dist/src/services/storefront.customer.metadata.service.js +225 -0
  102. package/dist/src/services/storefront.customer.metadata.service.test.d.ts +1 -0
  103. package/dist/src/services/storefront.customer.metadata.service.test.js +271 -0
  104. package/dist/src/services/storefront.order.service.d.ts +45 -0
  105. package/dist/src/services/storefront.order.service.js +99 -0
  106. package/dist/src/services/storefront.order.service.test.d.ts +1 -0
  107. package/dist/src/services/storefront.order.service.test.js +158 -0
  108. package/dist/src/services/storefront.product.service.d.ts +52 -0
  109. package/dist/src/services/storefront.product.service.js +75 -0
  110. package/dist/src/services/storefront.product.service.test.d.ts +1 -0
  111. package/dist/src/services/storefront.product.service.test.js +120 -0
  112. package/dist/src/services/storefront.store.service.d.ts +52 -0
  113. package/dist/src/services/storefront.store.service.js +140 -0
  114. package/dist/src/services/storefront.store.service.test.d.ts +1 -0
  115. package/dist/src/services/storefront.store.service.test.js +90 -0
  116. package/dist/src/services/user.service.d.ts +16 -0
  117. package/dist/src/services/user.service.js +37 -0
  118. package/dist/src/services/user.service.test.d.ts +1 -0
  119. package/dist/src/services/user.service.test.js +52 -0
  120. package/dist/src/services/utils/withAuthReset.d.ts +3 -0
  121. package/dist/src/services/utils/withAuthReset.js +8 -0
  122. package/dist/src/types/types.d.ts +93 -0
  123. package/dist/src/types/types.js +82 -0
  124. package/dist/src/types/types.test.d.ts +1 -0
  125. package/dist/src/types/types.test.js +25 -0
  126. package/dist/src/utils/cache-import.d.ts +3 -0
  127. package/dist/src/utils/cache-import.js +2 -0
  128. package/dist/src/utils/networking-import.d.ts +4 -0
  129. package/dist/src/utils/networking-import.js +3 -0
  130. package/dist/src/utils/rxjs-import.d.ts +5 -0
  131. package/dist/src/utils/rxjs-import.js +5 -0
  132. package/package.json +1 -1
@@ -0,0 +1,91 @@
1
+ import { ProviderType, NetworkingConfig, NetworkingUIEventWrapped, HttpResponse } from "../types/types";
2
+ import { SmessService } from "./smess.service";
3
+ import { BehaviorSubject, Observable } from "rxjs";
4
+ export type StorefrontCustomerMetadataTarget = "metadata-get" | "favorites-add" | "favorites-list" | "favorites-update-category" | "favorites-remove" | "favorites-categories" | "preferences-update" | "product-view-record" | "recent-searches" | "recently-viewed";
5
+ export interface AddFavoriteRequest {
6
+ productId: number;
7
+ }
8
+ export interface UpdateFavoriteCategoryRequest {
9
+ category: string;
10
+ }
11
+ export interface UpdatePreferencesRequest {
12
+ preferences: Record<string, unknown>;
13
+ }
14
+ export interface RecordProductViewRequest {
15
+ productId: number;
16
+ }
17
+ export declare class StorefrontCustomerMetadataProvider implements ProviderType {
18
+ private readonly config;
19
+ private readonly target;
20
+ private readonly $authToken;
21
+ constructor(config: NetworkingConfig, target: StorefrontCustomerMetadataTarget, $authToken: BehaviorSubject<string | null>);
22
+ get baseURL(): string;
23
+ get path(): string;
24
+ get method(): string;
25
+ get headers(): Record<string, string>;
26
+ getPath(...queryParams: unknown[]): string;
27
+ }
28
+ export declare class StorefrontCustomerMetadataService {
29
+ private readonly config;
30
+ private readonly $authToken;
31
+ constructor(config: NetworkingConfig, $authToken: BehaviorSubject<string | null>);
32
+ provider(target: StorefrontCustomerMetadataTarget): SmessService<StorefrontCustomerMetadataProvider>;
33
+ /**
34
+ * Check if user is authenticated
35
+ */
36
+ private checkAuthentication;
37
+ /**
38
+ * Create authentication required error
39
+ */
40
+ private createAuthRequiredError;
41
+ /**
42
+ * Get customer metadata
43
+ * GET /storefront/customer/metadata?store_id={storeId}
44
+ */
45
+ getMetadata(storeId: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
46
+ /**
47
+ * Add favorite product
48
+ * POST /storefront/customer/favorites?store_id={storeId}
49
+ */
50
+ addFavorite(storeId: number, payload: AddFavoriteRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
51
+ /**
52
+ * List favorite products
53
+ * GET /storefront/customer/favorites?store_id={storeId}&category={category}
54
+ */
55
+ listFavorites(storeId: number, category?: string): Observable<NetworkingUIEventWrapped<HttpResponse>>;
56
+ /**
57
+ * Update favorite product category
58
+ * PUT /storefront/customer/favorites/{productId}/category?store_id={storeId}
59
+ */
60
+ updateFavoriteCategory(productId: number, storeId: number, payload: UpdateFavoriteCategoryRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
61
+ /**
62
+ * Remove favorite product
63
+ * DELETE /storefront/customer/favorites/{productId}?store_id={storeId}
64
+ */
65
+ removeFavorite(productId: number, storeId: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
66
+ /**
67
+ * List favorite categories
68
+ * GET /storefront/customer/favorites/categories?store_id={storeId}
69
+ */
70
+ listFavoriteCategories(storeId: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
71
+ /**
72
+ * Update customer preferences
73
+ * PUT /storefront/customer/preferences?store_id={storeId}
74
+ */
75
+ updatePreferences(storeId: number, payload: UpdatePreferencesRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
76
+ /**
77
+ * Record product view
78
+ * POST /storefront/customer/product-view?store_id={storeId}
79
+ */
80
+ recordProductView(storeId: number, payload: RecordProductViewRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
81
+ /**
82
+ * Get recent searches
83
+ * GET /storefront/customer/recent-searches?store_id={storeId}
84
+ */
85
+ getRecentSearches(storeId: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
86
+ /**
87
+ * Get recently viewed products
88
+ * GET /storefront/customer/recently-viewed?store_id={storeId}&limit={limit}
89
+ */
90
+ getRecentlyViewed(storeId: number, limit?: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
91
+ }
@@ -0,0 +1,225 @@
1
+ import { NetworkingUIEventWrapped, AlertModel, AlertButtonModel, } from "../types/types";
2
+ import { Accept, SMESSHeader, SmessService } from "./smess.service";
3
+ import { of } from "rxjs";
4
+ export class StorefrontCustomerMetadataProvider {
5
+ constructor(config, target, $authToken) {
6
+ this.config = config;
7
+ this.target = target;
8
+ this.$authToken = $authToken;
9
+ }
10
+ get baseURL() {
11
+ return this.config.version
12
+ ? `${this.config.baseUrl}/${this.config.version}`
13
+ : this.config.baseUrl;
14
+ }
15
+ get path() {
16
+ switch (this.target) {
17
+ case "metadata-get":
18
+ return "/storefront/customer/metadata";
19
+ case "favorites-add":
20
+ return "/storefront/customer/favorites";
21
+ case "favorites-list":
22
+ return "/storefront/customer/favorites";
23
+ case "favorites-update-category":
24
+ return "/storefront/customer/favorites/${productId}/category";
25
+ case "favorites-remove":
26
+ return "/storefront/customer/favorites/${productId}";
27
+ case "favorites-categories":
28
+ return "/storefront/customer/favorites/categories";
29
+ case "preferences-update":
30
+ return "/storefront/customer/preferences";
31
+ case "product-view-record":
32
+ return "/storefront/customer/product-view";
33
+ case "recent-searches":
34
+ return "/storefront/customer/recent-searches";
35
+ case "recently-viewed":
36
+ return "/storefront/customer/recently-viewed";
37
+ default:
38
+ return "/storefront/customer/metadata";
39
+ }
40
+ }
41
+ get method() {
42
+ switch (this.target) {
43
+ case "metadata-get":
44
+ case "favorites-list":
45
+ case "favorites-categories":
46
+ case "recent-searches":
47
+ case "recently-viewed":
48
+ return "GET";
49
+ case "favorites-add":
50
+ case "product-view-record":
51
+ return "POST";
52
+ case "favorites-update-category":
53
+ case "preferences-update":
54
+ return "PUT";
55
+ case "favorites-remove":
56
+ return "DELETE";
57
+ default:
58
+ return "GET";
59
+ }
60
+ }
61
+ get headers() {
62
+ let headers = SmessService.getHeaders(Accept.V1, this.$authToken.value);
63
+ if (this.config.clientId) {
64
+ headers[SMESSHeader.ClientId] = this.config.clientId;
65
+ }
66
+ if (this.config.apiKey) {
67
+ headers[SMESSHeader.ApiKey] = this.config.apiKey;
68
+ }
69
+ return SmessService.filterHeaders(headers);
70
+ }
71
+ getPath(...queryParams) {
72
+ let definedPath = this.path;
73
+ const params = definedPath.match(/\$\{(.+?)\}/g);
74
+ params?.forEach((value, index) => {
75
+ definedPath = definedPath.replace(value, String(queryParams[index]));
76
+ });
77
+ return definedPath;
78
+ }
79
+ }
80
+ export class StorefrontCustomerMetadataService {
81
+ constructor(config, $authToken) {
82
+ this.config = config;
83
+ this.$authToken = $authToken;
84
+ }
85
+ provider(target) {
86
+ const targetWrapper = new StorefrontCustomerMetadataProvider(this.config, target, this.$authToken);
87
+ return new SmessService(targetWrapper);
88
+ }
89
+ /**
90
+ * Check if user is authenticated
91
+ */
92
+ checkAuthentication() {
93
+ return this.$authToken.value !== null && this.$authToken.value !== "";
94
+ }
95
+ /**
96
+ * Create authentication required error
97
+ */
98
+ createAuthRequiredError() {
99
+ const alertModel = new AlertModel("Authentication required to access customer metadata", 401, true, "Authentication Required", null, [AlertButtonModel.buttonYes()]);
100
+ return of(NetworkingUIEventWrapped.failed(alertModel));
101
+ }
102
+ /**
103
+ * Get customer metadata
104
+ * GET /storefront/customer/metadata?store_id={storeId}
105
+ */
106
+ getMetadata(storeId) {
107
+ if (!this.checkAuthentication()) {
108
+ return this.createAuthRequiredError();
109
+ }
110
+ return this.provider("metadata-get").request({
111
+ store_id: storeId,
112
+ });
113
+ }
114
+ /**
115
+ * Add favorite product
116
+ * POST /storefront/customer/favorites?store_id={storeId}
117
+ */
118
+ addFavorite(storeId, payload) {
119
+ if (!this.checkAuthentication()) {
120
+ return this.createAuthRequiredError();
121
+ }
122
+ return this.provider("favorites-add").request({
123
+ ...payload,
124
+ store_id: storeId,
125
+ });
126
+ }
127
+ /**
128
+ * List favorite products
129
+ * GET /storefront/customer/favorites?store_id={storeId}&category={category}
130
+ */
131
+ listFavorites(storeId, category) {
132
+ if (!this.checkAuthentication()) {
133
+ return this.createAuthRequiredError();
134
+ }
135
+ const params = { store_id: storeId };
136
+ if (category) {
137
+ params.category = category;
138
+ }
139
+ return this.provider("favorites-list").request(params);
140
+ }
141
+ /**
142
+ * Update favorite product category
143
+ * PUT /storefront/customer/favorites/{productId}/category?store_id={storeId}
144
+ */
145
+ updateFavoriteCategory(productId, storeId, payload) {
146
+ if (!this.checkAuthentication()) {
147
+ return this.createAuthRequiredError();
148
+ }
149
+ return this.provider("favorites-update-category").request({ ...payload, store_id: storeId }, undefined, productId);
150
+ }
151
+ /**
152
+ * Remove favorite product
153
+ * DELETE /storefront/customer/favorites/{productId}?store_id={storeId}
154
+ */
155
+ removeFavorite(productId, storeId) {
156
+ if (!this.checkAuthentication()) {
157
+ return this.createAuthRequiredError();
158
+ }
159
+ return this.provider("favorites-remove").request({ store_id: storeId }, undefined, productId);
160
+ }
161
+ /**
162
+ * List favorite categories
163
+ * GET /storefront/customer/favorites/categories?store_id={storeId}
164
+ */
165
+ listFavoriteCategories(storeId) {
166
+ if (!this.checkAuthentication()) {
167
+ return this.createAuthRequiredError();
168
+ }
169
+ return this.provider("favorites-categories").request({
170
+ store_id: storeId,
171
+ });
172
+ }
173
+ /**
174
+ * Update customer preferences
175
+ * PUT /storefront/customer/preferences?store_id={storeId}
176
+ */
177
+ updatePreferences(storeId, payload) {
178
+ if (!this.checkAuthentication()) {
179
+ return this.createAuthRequiredError();
180
+ }
181
+ return this.provider("preferences-update").request({
182
+ ...payload,
183
+ store_id: storeId,
184
+ });
185
+ }
186
+ /**
187
+ * Record product view
188
+ * POST /storefront/customer/product-view?store_id={storeId}
189
+ */
190
+ recordProductView(storeId, payload) {
191
+ if (!this.checkAuthentication()) {
192
+ return this.createAuthRequiredError();
193
+ }
194
+ return this.provider("product-view-record").request({
195
+ ...payload,
196
+ store_id: storeId,
197
+ });
198
+ }
199
+ /**
200
+ * Get recent searches
201
+ * GET /storefront/customer/recent-searches?store_id={storeId}
202
+ */
203
+ getRecentSearches(storeId) {
204
+ if (!this.checkAuthentication()) {
205
+ return this.createAuthRequiredError();
206
+ }
207
+ return this.provider("recent-searches").request({
208
+ store_id: storeId,
209
+ });
210
+ }
211
+ /**
212
+ * Get recently viewed products
213
+ * GET /storefront/customer/recently-viewed?store_id={storeId}&limit={limit}
214
+ */
215
+ getRecentlyViewed(storeId, limit) {
216
+ if (!this.checkAuthentication()) {
217
+ return this.createAuthRequiredError();
218
+ }
219
+ const params = { store_id: storeId };
220
+ if (limit !== undefined) {
221
+ params.limit = limit;
222
+ }
223
+ return this.provider("recently-viewed").request(params);
224
+ }
225
+ }
@@ -0,0 +1,271 @@
1
+ import { StorefrontCustomerMetadataService, StorefrontCustomerMetadataProvider, } from "./storefront.customer.metadata.service";
2
+ import { NetworkingUIEventWrapped, AlertModel, } from "../types/types";
3
+ import { of, BehaviorSubject } from "rxjs";
4
+ describe("StorefrontCustomerMetadataService", () => {
5
+ const config = {
6
+ baseUrl: "https://api.example.com",
7
+ version: "api/v1",
8
+ isProd: false,
9
+ clientId: "test-client-id",
10
+ apiKey: "test-api-key",
11
+ };
12
+ let service;
13
+ let $authToken;
14
+ beforeEach(() => {
15
+ $authToken = new BehaviorSubject(null);
16
+ service = new StorefrontCustomerMetadataService(config, $authToken);
17
+ });
18
+ describe("StorefrontCustomerMetadataProvider", () => {
19
+ it("should generate correct path for metadata-get", () => {
20
+ const provider = new StorefrontCustomerMetadataProvider(config, "metadata-get", $authToken);
21
+ expect(provider.path).toBe("/storefront/customer/metadata");
22
+ expect(provider.method).toBe("GET");
23
+ });
24
+ it("should generate correct path for favorites-add", () => {
25
+ const provider = new StorefrontCustomerMetadataProvider(config, "favorites-add", $authToken);
26
+ expect(provider.path).toBe("/storefront/customer/favorites");
27
+ expect(provider.method).toBe("POST");
28
+ });
29
+ it("should generate correct path for favorites-update-category", () => {
30
+ const provider = new StorefrontCustomerMetadataProvider(config, "favorites-update-category", $authToken);
31
+ expect(provider.path).toBe("/storefront/customer/favorites/${productId}/category");
32
+ expect(provider.method).toBe("PUT");
33
+ expect(provider.getPath(123)).toBe("/storefront/customer/favorites/123/category");
34
+ });
35
+ it("should include auth token in headers", () => {
36
+ $authToken.next("test-auth-token");
37
+ const provider = new StorefrontCustomerMetadataProvider(config, "metadata-get", $authToken);
38
+ const headers = provider.headers;
39
+ expect(headers["Authorization"]).toBe("Bearer test-auth-token");
40
+ });
41
+ });
42
+ describe("getMetadata", () => {
43
+ it("should return authentication error when not authenticated", async () => {
44
+ const result = await service.getMetadata(1).toPromise();
45
+ expect(result?.hasFailed).toBe(true);
46
+ expect(result?.alertModel).toBeInstanceOf(AlertModel);
47
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
48
+ });
49
+ it("should get metadata successfully when authenticated", async () => {
50
+ $authToken.next("test-auth-token");
51
+ const response = {
52
+ data: { customerId: "123", preferences: {} },
53
+ };
54
+ jest.spyOn(service, "provider").mockReturnValue({
55
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
56
+ });
57
+ const result = await service.getMetadata(1).toPromise();
58
+ expect(result?.hasSuccess).toBe(true);
59
+ expect(result?.response).toEqual(response);
60
+ });
61
+ });
62
+ describe("addFavorite", () => {
63
+ it("should return authentication error when not authenticated", async () => {
64
+ const payload = { productId: 123 };
65
+ const result = await service.addFavorite(1, payload).toPromise();
66
+ expect(result?.hasFailed).toBe(true);
67
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
68
+ });
69
+ it("should add favorite successfully when authenticated", async () => {
70
+ $authToken.next("test-auth-token");
71
+ const payload = { productId: 123 };
72
+ const response = {
73
+ data: { id: 1, productId: 123 },
74
+ };
75
+ jest.spyOn(service, "provider").mockReturnValue({
76
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
77
+ });
78
+ const result = await service.addFavorite(1, payload).toPromise();
79
+ expect(result?.hasSuccess).toBe(true);
80
+ expect(result?.response).toEqual(response);
81
+ });
82
+ });
83
+ describe("listFavorites", () => {
84
+ it("should return authentication error when not authenticated", async () => {
85
+ const result = await service.listFavorites(1).toPromise();
86
+ expect(result?.hasFailed).toBe(true);
87
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
88
+ });
89
+ it("should list favorites successfully when authenticated", async () => {
90
+ $authToken.next("test-auth-token");
91
+ const response = {
92
+ data: { favorites: [] },
93
+ };
94
+ jest.spyOn(service, "provider").mockReturnValue({
95
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
96
+ });
97
+ const result = await service.listFavorites(1).toPromise();
98
+ expect(result?.hasSuccess).toBe(true);
99
+ expect(result?.response).toEqual(response);
100
+ });
101
+ it("should list favorites with category filter", async () => {
102
+ $authToken.next("test-auth-token");
103
+ const response = {
104
+ data: { favorites: [] },
105
+ };
106
+ jest.spyOn(service, "provider").mockReturnValue({
107
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
108
+ });
109
+ const result = await service
110
+ .listFavorites(1, "Electronics")
111
+ .toPromise();
112
+ expect(result?.hasSuccess).toBe(true);
113
+ });
114
+ });
115
+ describe("updateFavoriteCategory", () => {
116
+ it("should return authentication error when not authenticated", async () => {
117
+ const payload = { category: "Books" };
118
+ const result = await service
119
+ .updateFavoriteCategory(123, 1, payload)
120
+ .toPromise();
121
+ expect(result?.hasFailed).toBe(true);
122
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
123
+ });
124
+ it("should update favorite category successfully when authenticated", async () => {
125
+ $authToken.next("test-auth-token");
126
+ const payload = { category: "Books" };
127
+ const response = {
128
+ data: { id: 1, category: "Books" },
129
+ };
130
+ jest.spyOn(service, "provider").mockReturnValue({
131
+ request: (_payload, _mockResponse, productId) => of(NetworkingUIEventWrapped.succeeded(response)),
132
+ });
133
+ const result = await service
134
+ .updateFavoriteCategory(123, 1, payload)
135
+ .toPromise();
136
+ expect(result?.hasSuccess).toBe(true);
137
+ expect(result?.response).toEqual(response);
138
+ });
139
+ });
140
+ describe("removeFavorite", () => {
141
+ it("should return authentication error when not authenticated", async () => {
142
+ const result = await service.removeFavorite(123, 1).toPromise();
143
+ expect(result?.hasFailed).toBe(true);
144
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
145
+ });
146
+ it("should remove favorite successfully when authenticated", async () => {
147
+ $authToken.next("test-auth-token");
148
+ const response = {
149
+ data: { message: "Favorite removed" },
150
+ };
151
+ jest.spyOn(service, "provider").mockReturnValue({
152
+ request: (_payload, _mockResponse, productId) => of(NetworkingUIEventWrapped.succeeded(response)),
153
+ });
154
+ const result = await service.removeFavorite(123, 1).toPromise();
155
+ expect(result?.hasSuccess).toBe(true);
156
+ expect(result?.response).toEqual(response);
157
+ });
158
+ });
159
+ describe("listFavoriteCategories", () => {
160
+ it("should return authentication error when not authenticated", async () => {
161
+ const result = await service.listFavoriteCategories(1).toPromise();
162
+ expect(result?.hasFailed).toBe(true);
163
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
164
+ });
165
+ it("should list favorite categories successfully when authenticated", async () => {
166
+ $authToken.next("test-auth-token");
167
+ const response = {
168
+ data: { categories: ["Books", "Electronics"] },
169
+ };
170
+ jest.spyOn(service, "provider").mockReturnValue({
171
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
172
+ });
173
+ const result = await service.listFavoriteCategories(1).toPromise();
174
+ expect(result?.hasSuccess).toBe(true);
175
+ expect(result?.response).toEqual(response);
176
+ });
177
+ });
178
+ describe("updatePreferences", () => {
179
+ it("should return authentication error when not authenticated", async () => {
180
+ const payload = { preferences: {} };
181
+ const result = await service.updatePreferences(1, payload).toPromise();
182
+ expect(result?.hasFailed).toBe(true);
183
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
184
+ });
185
+ it("should update preferences successfully when authenticated", async () => {
186
+ $authToken.next("test-auth-token");
187
+ const payload = {
188
+ preferences: { theme: "dark" },
189
+ };
190
+ const response = {
191
+ data: { preferences: { theme: "dark" } },
192
+ };
193
+ jest.spyOn(service, "provider").mockReturnValue({
194
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
195
+ });
196
+ const result = await service.updatePreferences(1, payload).toPromise();
197
+ expect(result?.hasSuccess).toBe(true);
198
+ expect(result?.response).toEqual(response);
199
+ });
200
+ });
201
+ describe("recordProductView", () => {
202
+ it("should return authentication error when not authenticated", async () => {
203
+ const payload = { productId: 123 };
204
+ const result = await service.recordProductView(1, payload).toPromise();
205
+ expect(result?.hasFailed).toBe(true);
206
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
207
+ });
208
+ it("should record product view successfully when authenticated", async () => {
209
+ $authToken.next("test-auth-token");
210
+ const payload = { productId: 123 };
211
+ const response = {
212
+ data: { message: "Product view recorded" },
213
+ };
214
+ jest.spyOn(service, "provider").mockReturnValue({
215
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
216
+ });
217
+ const result = await service.recordProductView(1, payload).toPromise();
218
+ expect(result?.hasSuccess).toBe(true);
219
+ expect(result?.response).toEqual(response);
220
+ });
221
+ });
222
+ describe("getRecentSearches", () => {
223
+ it("should return authentication error when not authenticated", async () => {
224
+ const result = await service.getRecentSearches(1).toPromise();
225
+ expect(result?.hasFailed).toBe(true);
226
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
227
+ });
228
+ it("should get recent searches successfully when authenticated", async () => {
229
+ $authToken.next("test-auth-token");
230
+ const response = {
231
+ data: { searches: ["laptop", "phone"] },
232
+ };
233
+ jest.spyOn(service, "provider").mockReturnValue({
234
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
235
+ });
236
+ const result = await service.getRecentSearches(1).toPromise();
237
+ expect(result?.hasSuccess).toBe(true);
238
+ expect(result?.response).toEqual(response);
239
+ });
240
+ });
241
+ describe("getRecentlyViewed", () => {
242
+ it("should return authentication error when not authenticated", async () => {
243
+ const result = await service.getRecentlyViewed(1).toPromise();
244
+ expect(result?.hasFailed).toBe(true);
245
+ expect(result?.alertModel?.httpErrorCode).toBe(401);
246
+ });
247
+ it("should get recently viewed successfully when authenticated", async () => {
248
+ $authToken.next("test-auth-token");
249
+ const response = {
250
+ data: { products: [] },
251
+ };
252
+ jest.spyOn(service, "provider").mockReturnValue({
253
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
254
+ });
255
+ const result = await service.getRecentlyViewed(1).toPromise();
256
+ expect(result?.hasSuccess).toBe(true);
257
+ expect(result?.response).toEqual(response);
258
+ });
259
+ it("should get recently viewed with limit", async () => {
260
+ $authToken.next("test-auth-token");
261
+ const response = {
262
+ data: { products: [] },
263
+ };
264
+ jest.spyOn(service, "provider").mockReturnValue({
265
+ request: () => of(NetworkingUIEventWrapped.succeeded(response)),
266
+ });
267
+ const result = await service.getRecentlyViewed(1, 10).toPromise();
268
+ expect(result?.hasSuccess).toBe(true);
269
+ });
270
+ });
271
+ });
@@ -0,0 +1,45 @@
1
+ import { ProviderType, NetworkingConfig, NetworkingUIEventWrapped, HttpResponse } from "../types/types";
2
+ import { SmessService } from "./smess.service";
3
+ import { BehaviorSubject, Observable } from "rxjs";
4
+ export type StorefrontOrderTarget = "order-list" | "order-detail" | "order-track";
5
+ export interface OrderListRequest {
6
+ page?: number;
7
+ limit?: number;
8
+ status?: string;
9
+ }
10
+ export interface TrackOrderRequest {
11
+ orderNumber: string;
12
+ email: string;
13
+ }
14
+ export declare class StorefrontOrderProvider implements ProviderType {
15
+ private readonly config;
16
+ private readonly target;
17
+ private readonly $authToken;
18
+ constructor(config: NetworkingConfig, target: StorefrontOrderTarget, $authToken: BehaviorSubject<string | null>);
19
+ get baseURL(): string;
20
+ get path(): string;
21
+ get method(): string;
22
+ get headers(): Record<string, string>;
23
+ getPath(...queryParams: unknown[]): string;
24
+ }
25
+ export declare class StorefrontOrderService {
26
+ private readonly config;
27
+ private readonly $authToken;
28
+ constructor(config: NetworkingConfig, $authToken: BehaviorSubject<string | null>);
29
+ provider(target: StorefrontOrderTarget): SmessService<StorefrontOrderProvider>;
30
+ /**
31
+ * List customer orders (requires authentication)
32
+ * GET /storefront/orders
33
+ */
34
+ listOrders(params?: OrderListRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
35
+ /**
36
+ * Get order details (requires authentication)
37
+ * GET /storefront/orders/{id}
38
+ */
39
+ getOrderDetail(id: number): Observable<NetworkingUIEventWrapped<HttpResponse>>;
40
+ /**
41
+ * Track guest order (no authentication required)
42
+ * POST /storefront/orders/track
43
+ */
44
+ trackOrder(payload: TrackOrderRequest): Observable<NetworkingUIEventWrapped<HttpResponse>>;
45
+ }