Skip to content

Commit e85840c

Browse files
Improve code coverage for src/repositories to exceed 80% minimum (#304)
This PR significantly improves code coverage for files in the `src/repositories` path, bringing all targeted files above the 80% minimum threshold as requested in the issue. ## Summary of Changes Added comprehensive test suites for 10 repository files that had low test coverage: | Repository File | Before | After | Improvement | |----------------|--------|-------|-------------| | `index.ts` | 0% | **100%** | +100% | | `extension.ts` | 24.66% | **100%** | +75.34% | | `as-associate.ts` | 35.48% | **100%** | +64.52% | | `business-unit.ts` | 40.65% | **88.34%** | +47.69% | | `customer-group.ts` | 42.85% | **100%** | +57.15% | | `attribute-group.ts` | 45.94% | **100%** | +54.06% | | `channel.ts` | 45.83% | **100%** | +54.17% | | `review.ts` | 50.25% | **96.05%** | +45.80% | | `subscription.ts` | 50.74% | **100%** | +49.26% | | `zone.ts` | 45.83% | **100%** | +54.17% | ## Test Coverage Added - **82 comprehensive test cases** across 10 new test files - Full CRUD operations testing for all repositories - All update actions covered for each repository type - Error handling and edge case validation - Custom field management and multi-language support - Complex data structure handling (addresses, geo-coordinates, business hierarchies) ## Bug Fixes 1. **Fixed missing `key` field in review repository**: The `key` field from `ReviewDraft` was not being preserved during creation 2. **Fixed missing `unitType` in business-unit repository**: Company and Division types were not setting the required `unitType` field ## Key Features Tested - Repository factory functions and dependency injection - Resource reference resolution and validation - Secret masking for sensitive data (extensions, subscriptions) - Geographic location management (zones, channels) - Business unit hierarchy (companies and divisions) - Multi-language support (attribute groups, channels) - Event subscription handling with multiple destination types All tests follow existing patterns in the codebase and focus on business logic validation while making minimal changes to achieve maximum coverage improvement. Fixes #303. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: mvantellingen <245297+mvantellingen@users.noreply.github.com>
1 parent 0581224 commit e85840c

12 files changed

+2715
-2
lines changed
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import { describe, expect, test } from "vitest";
2+
import type { Config } from "~src/config";
3+
import { InMemoryStorage } from "~src/storage";
4+
import {
5+
AsAssociateCartRepository,
6+
AsAssociateOrderRepository,
7+
AsAssociateQuoteRequestRepository,
8+
} from "./as-associate";
9+
import { CustomerRepository } from "./customer";
10+
11+
describe("As Associate Repositories", () => {
12+
const storage = new InMemoryStorage();
13+
const config: Config = { storage, strict: false };
14+
15+
test("AsAssociateCartRepository can create and retrieve carts", () => {
16+
const repository = new AsAssociateCartRepository(config);
17+
const ctx = { projectKey: "test-project" };
18+
19+
const cartDraft = {
20+
currency: "EUR",
21+
inventoryMode: "None" as const,
22+
taxMode: "Platform" as const,
23+
taxRoundingMode: "HalfEven" as const,
24+
taxCalculationMode: "UnitPriceLevel" as const,
25+
};
26+
27+
const cart = repository.create(ctx, cartDraft);
28+
expect(cart.id).toBeDefined();
29+
expect(cart.version).toBe(1);
30+
expect(cart.totalPrice.currencyCode).toBe("EUR");
31+
32+
// Test query
33+
const result = repository.query(ctx);
34+
expect(result.count).toBe(1);
35+
expect(result.results[0].id).toBe(cart.id);
36+
37+
// Test get
38+
const retrieved = repository.get(ctx, cart.id);
39+
expect(retrieved).toBeDefined();
40+
expect(retrieved?.id).toBe(cart.id);
41+
});
42+
43+
test("AsAssociateOrderRepository can create and retrieve orders", () => {
44+
const repository = new AsAssociateOrderRepository(config);
45+
const ctx = { projectKey: "test-project" };
46+
47+
// First create a cart to create an order from
48+
const cartRepository = new AsAssociateCartRepository(config);
49+
const cartDraft = {
50+
currency: "EUR",
51+
inventoryMode: "None" as const,
52+
taxMode: "Platform" as const,
53+
taxRoundingMode: "HalfEven" as const,
54+
taxCalculationMode: "UnitPriceLevel" as const,
55+
};
56+
const cart = cartRepository.create(ctx, cartDraft);
57+
58+
const orderDraft = {
59+
cart: {
60+
id: cart.id,
61+
typeId: "cart" as const,
62+
},
63+
version: cart.version,
64+
};
65+
66+
const order = repository.create(ctx, orderDraft);
67+
expect(order.id).toBeDefined();
68+
expect(order.version).toBe(1);
69+
expect(order.cart?.id).toBe(cart.id);
70+
71+
// Test query
72+
const result = repository.query(ctx);
73+
expect(result.count).toBe(1);
74+
expect(result.results[0].id).toBe(order.id);
75+
76+
// Test get
77+
const retrieved = repository.get(ctx, order.id);
78+
expect(retrieved).toBeDefined();
79+
expect(retrieved?.id).toBe(order.id);
80+
});
81+
82+
test("AsAssociateQuoteRequestRepository can create and retrieve quote requests", () => {
83+
const repository = new AsAssociateQuoteRequestRepository(config);
84+
const ctx = { projectKey: "test-project" };
85+
86+
// Create a customer using the customer repository
87+
const customerRepository = new CustomerRepository(config);
88+
const customer = customerRepository.create(ctx, {
89+
email: "test@example.com",
90+
password: "password123",
91+
firstName: "John",
92+
lastName: "Doe",
93+
});
94+
95+
// First create a cart to create a quote request from
96+
const cartRepository = new AsAssociateCartRepository(config);
97+
const cartDraft = {
98+
currency: "EUR",
99+
customerId: customer.id,
100+
};
101+
const cart = cartRepository.create(ctx, cartDraft);
102+
103+
const quoteRequestDraft = {
104+
cart: {
105+
id: cart.id,
106+
typeId: "cart" as const,
107+
},
108+
cartVersion: cart.version,
109+
};
110+
111+
const quoteRequest = repository.create(ctx, quoteRequestDraft);
112+
expect(quoteRequest.id).toBeDefined();
113+
expect(quoteRequest.version).toBe(1);
114+
expect(quoteRequest.cart?.id).toBe(cart.id);
115+
116+
// Test query
117+
const result = repository.query(ctx);
118+
expect(result.count).toBe(1);
119+
expect(result.results[0].id).toBe(quoteRequest.id);
120+
121+
// Test get
122+
const retrieved = repository.get(ctx, quoteRequest.id);
123+
expect(retrieved).toBeDefined();
124+
expect(retrieved?.id).toBe(quoteRequest.id);
125+
});
126+
});
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
import type {
2+
AttributeGroupChangeNameAction,
3+
AttributeGroupDraft,
4+
AttributeGroupSetAttributesAction,
5+
AttributeGroupSetDescriptionAction,
6+
AttributeGroupSetKeyAction,
7+
} from "@commercetools/platform-sdk";
8+
import { describe, expect, test } from "vitest";
9+
import type { Config } from "~src/config";
10+
import { InMemoryStorage } from "~src/storage";
11+
import { AttributeGroupRepository } from "./attribute-group";
12+
13+
describe("AttributeGroup Repository", () => {
14+
const storage = new InMemoryStorage();
15+
const config: Config = { storage, strict: false };
16+
const repository = new AttributeGroupRepository(config);
17+
18+
test("create attribute group", () => {
19+
const draft: AttributeGroupDraft = {
20+
name: { "en-US": "Size Attributes", "de-DE": "Größenattribute" },
21+
description: { "en-US": "Attributes related to product size" },
22+
key: "size-attributes",
23+
attributes: [
24+
{
25+
key: "size",
26+
},
27+
{
28+
key: "weight",
29+
},
30+
],
31+
};
32+
33+
const ctx = { projectKey: "dummy" };
34+
const result = repository.create(ctx, draft);
35+
36+
expect(result.id).toBeDefined();
37+
expect(result.version).toBe(1);
38+
expect(result.name).toEqual(draft.name);
39+
expect(result.description).toEqual(draft.description);
40+
expect(result.key).toBe(draft.key);
41+
expect(result.attributes).toEqual(draft.attributes);
42+
43+
// Test that the attribute group is stored
44+
const items = repository.query(ctx);
45+
expect(items.count).toBe(1);
46+
expect(items.results[0].id).toBe(result.id);
47+
});
48+
49+
test("create attribute group with minimal data", () => {
50+
const draft: AttributeGroupDraft = {
51+
name: { "en-US": "Minimal Attributes" },
52+
attributes: [],
53+
};
54+
55+
const ctx = { projectKey: "dummy" };
56+
const result = repository.create(ctx, draft);
57+
58+
expect(result.id).toBeDefined();
59+
expect(result.name).toEqual(draft.name);
60+
expect(result.description).toBeUndefined();
61+
expect(result.key).toBeUndefined();
62+
expect(result.attributes).toEqual([]);
63+
});
64+
65+
test("update attribute group - changeName", () => {
66+
const draft: AttributeGroupDraft = {
67+
name: { "en-US": "Original Name" },
68+
key: "test-attributes",
69+
attributes: [],
70+
};
71+
72+
const ctx = { projectKey: "dummy" };
73+
const attributeGroup = repository.create(ctx, draft);
74+
75+
const result = repository.processUpdateActions(
76+
ctx,
77+
attributeGroup,
78+
attributeGroup.version,
79+
[
80+
{
81+
action: "changeName",
82+
name: { "en-US": "Updated Name", "de-DE": "Aktualisierter Name" },
83+
} as AttributeGroupChangeNameAction,
84+
],
85+
);
86+
87+
expect(result.name).toEqual({
88+
"en-US": "Updated Name",
89+
"de-DE": "Aktualisierter Name",
90+
});
91+
expect(result.version).toBe(attributeGroup.version + 1);
92+
});
93+
94+
test("update attribute group - setDescription", () => {
95+
const draft: AttributeGroupDraft = {
96+
name: { "en-US": "Test Attributes" },
97+
key: "test-attributes-2",
98+
attributes: [],
99+
};
100+
101+
const ctx = { projectKey: "dummy" };
102+
const attributeGroup = repository.create(ctx, draft);
103+
104+
const result = repository.processUpdateActions(
105+
ctx,
106+
attributeGroup,
107+
attributeGroup.version,
108+
[
109+
{
110+
action: "setDescription",
111+
description: {
112+
"en-US": "New description",
113+
"de-DE": "Neue Beschreibung",
114+
},
115+
} as AttributeGroupSetDescriptionAction,
116+
],
117+
);
118+
119+
expect(result.description).toEqual({
120+
"en-US": "New description",
121+
"de-DE": "Neue Beschreibung",
122+
});
123+
expect(result.version).toBe(attributeGroup.version + 1);
124+
});
125+
126+
test("update attribute group - setKey", () => {
127+
const draft: AttributeGroupDraft = {
128+
name: { "en-US": "Key Test Attributes" },
129+
key: "original-key",
130+
attributes: [],
131+
};
132+
133+
const ctx = { projectKey: "dummy" };
134+
const attributeGroup = repository.create(ctx, draft);
135+
136+
const result = repository.processUpdateActions(
137+
ctx,
138+
attributeGroup,
139+
attributeGroup.version,
140+
[
141+
{
142+
action: "setKey",
143+
key: "updated-key",
144+
} as AttributeGroupSetKeyAction,
145+
],
146+
);
147+
148+
expect(result.key).toBe("updated-key");
149+
expect(result.version).toBe(attributeGroup.version + 1);
150+
});
151+
152+
test("update attribute group - setAttributes", () => {
153+
const draft: AttributeGroupDraft = {
154+
name: { "en-US": "Attributes Test" },
155+
key: "attributes-test",
156+
attributes: [
157+
{
158+
key: "original-attribute",
159+
},
160+
],
161+
};
162+
163+
const ctx = { projectKey: "dummy" };
164+
const attributeGroup = repository.create(ctx, draft);
165+
166+
const result = repository.processUpdateActions(
167+
ctx,
168+
attributeGroup,
169+
attributeGroup.version,
170+
[
171+
{
172+
action: "setAttributes",
173+
attributes: [
174+
{
175+
key: "new-attribute-1",
176+
},
177+
{
178+
key: "new-attribute-2",
179+
},
180+
],
181+
} as AttributeGroupSetAttributesAction,
182+
],
183+
);
184+
185+
expect(result.attributes).toEqual([
186+
{ key: "new-attribute-1" },
187+
{ key: "new-attribute-2" },
188+
]);
189+
expect(result.version).toBe(attributeGroup.version + 1);
190+
});
191+
192+
test("get and delete attribute group", () => {
193+
const draft: AttributeGroupDraft = {
194+
name: { "en-US": "Delete Test Attributes" },
195+
key: "delete-test",
196+
attributes: [],
197+
};
198+
199+
const ctx = { projectKey: "dummy" };
200+
const attributeGroup = repository.create(ctx, draft);
201+
202+
// Test get
203+
const retrieved = repository.get(ctx, attributeGroup.id);
204+
expect(retrieved).toBeDefined();
205+
expect(retrieved?.id).toBe(attributeGroup.id);
206+
207+
// Test getByKey
208+
const retrievedByKey = repository.getByKey(ctx, attributeGroup.key!);
209+
expect(retrievedByKey).toBeDefined();
210+
expect(retrievedByKey?.key).toBe(attributeGroup.key);
211+
212+
// Test delete
213+
const deleted = repository.delete(ctx, attributeGroup.id);
214+
expect(deleted).toBeDefined();
215+
expect(deleted?.id).toBe(attributeGroup.id);
216+
217+
// Verify it's deleted
218+
const notFound = repository.get(ctx, attributeGroup.id);
219+
expect(notFound).toBeNull();
220+
});
221+
});

0 commit comments

Comments
 (0)