Skip to content

Add comprehensive test coverage enhancement #204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ coverage
.env
.dccache
dist/*
*.log
*.log
.nx/
18 changes: 2 additions & 16 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1,18 +1,4 @@
fileignoreconfig:
- filename: test/unit/persistance/local-storage.spec.ts
checksum: da6638b676c34274279d80539983a5dfcf5e729ec65d6a535d7939b6ba7c9b58
- filename: test/unit/cache.spec.ts
checksum: cadf177ffc4ce8c271e8b49fd227947351afa7cade5c7cd902cda78d0f91ba5b
- filename: test/unit/persistance/preference-store.spec.ts
checksum: 0f3457f8ea8b149c5de1d6585c78eb4cea0d2ac00ca69cdc294c44fe29ea3c11
- filename: test/unit/contentstack.spec.ts
checksum: 267e4857af531bd3e5f080c3630922169a0c161355a6b185f1ee2716c5e60c45
- filename: test/unit/utils.spec.ts
checksum: b447bcd7d3b4ff83846dc0f492f1c7f52f80c46f341aabbf7570a16ed17d8232
- filename: src/lib/types.ts
checksum: a5e87bfe625b8cef8714545c07cfbe3ea05b07c8cb495fef532c610b37d82140
- filename: test/unit/persistance/preference-store.spec.ts
checksum: 5d31522fb28b95b0b243b8f3d8499dcf4c5c80c0ea24f895802a724136985e37
- filename: test/api/live-preview.spec.ts
checksum: 577c1407bfd80d2e6a7717f55b02eb0b93e37050d7c985b85f2bb4bf99f430f0
- filename: test/unit/query-optimization-comprehensive.spec.ts
checksum: f5aaf6c784d7c101a05ca513c584bbd6e95f963d1e42779f2596050d9bcbac96
version: "1.0"
329 changes: 329 additions & 0 deletions test/api/entry-variants.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,329 @@
import { stackInstance } from '../utils/stack-instance';
import { TEntry } from './types';

const stack = stackInstance();
const contentTypeUid = process.env.CONTENT_TYPE_UID || 'sample_content_type';
const entryUid = process.env.ENTRY_UID || 'sample_entry';
const variantUid = process.env.VARIANT_UID || 'sample_variant';

describe('Entry Variants API Tests', () => {
describe('Single Entry Variant Operations', () => {
it('should fetch entry with specific variant', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Note: The SDK uses variants() method and sets x-cs-variant-uid header
// The actual variant data structure depends on the CMS response
});

it('should fetch entry with multiple variants', async () => {
const variantUids = [variantUid, 'variant_2', 'variant_3'];

const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUids)
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Multiple variants are passed as comma-separated string in header
});

it('should include metadata with variant requests', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.includeMetadata()
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Metadata should be included when requested
});

it('should apply variant with reference inclusion', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.includeReference()
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Variants should work with reference inclusion
});
});

describe('Entry Variants Query Operations', () => {
it('should query entries with specific variant', async () => {
const result = await stack.contentType(contentTypeUid).entry()
.variants(variantUid)
.find<{ entries: TEntry[] }>();

expect(result).toBeDefined();
expect(result.entries).toBeDefined();
expect(result.entries!.length).toBeGreaterThan(0);

// The variant header is sent, affecting the response
const entry = result.entries![0] as any;
expect(entry.uid).toBeDefined();
});

it('should query entries with multiple variants', async () => {
const variantUids = [variantUid, 'variant_2'];

const result = await stack.contentType(contentTypeUid).entry()
.variants(variantUids)
.find<{ entries: TEntry[] }>();

expect(result).toBeDefined();
expect(result.entries).toBeDefined();
expect(result.entries!.length).toBeGreaterThan(0);

// Multiple variants are passed as comma-separated string
const entry = result.entries![0] as any;
expect(entry.uid).toBeDefined();
});

it('should filter entries with variant using query', async () => {
const result = await stack.contentType(contentTypeUid).entry()
.variants(variantUid)
.query()
.equalTo('uid', entryUid)
.find<{ entries: TEntry[] }>();

expect(result).toBeDefined();
expect(result.entries).toBeDefined();

if (result.entries && result.entries.length > 0) {
result.entries.forEach((entry: any) => {
expect(entry.uid).toBe(entryUid);
});
}
});

it('should support pagination with variant queries', async () => {
const result = await stack.contentType(contentTypeUid).entry()
.variants(variantUid)
.limit(5)
.skip(0)
.find<{ entries: TEntry[] }>();

expect(result).toBeDefined();
expect(result.entries).toBeDefined();
expect(result.entries!.length).toBeLessThanOrEqual(5);

if (result.entries && result.entries.length > 0) {
const entry = result.entries[0] as any;
expect(entry.uid).toBeDefined();
}
});

it('should include count with variant queries', async () => {
const result = await stack.contentType(contentTypeUid).entry()
.variants(variantUid)
.includeCount()
.find<{ entries: TEntry[], count: number }>();

expect(result).toBeDefined();
expect(result.entries).toBeDefined();
expect(result.count).toBeDefined();
expect(typeof result.count).toBe('number');

if (result.entries && result.entries.length > 0) {
const entry = result.entries[0] as any;
expect(entry.uid).toBeDefined();
}
});
});

describe('Variant Field and Content Operations', () => {
it('should fetch entry with variant and content type', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.includeContentType()
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
expect(result.title).toBeDefined();
// Content type should be included with variant
});

it('should fetch entry with variant and specific fields only', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.only(['title', 'uid'])
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
expect(result.title).toBeDefined();
// Only specified fields should be returned
});

it('should handle variant with embedded items', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.includeEmbeddedItems()
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Embedded items should be included with variant
});
});

describe('Variant Performance and Basic Tests', () => {
it('should apply variant with additional parameters', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.addParams({ 'variant_context': 'mobile' })
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Variant context is passed as additional parameter
});

it('should handle variant with multiple parameters', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.addParams({
'variant_context': 'mobile',
'user_segment': 'premium'
})
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Multiple parameters should be handled
});

it('should handle variant with locale specification', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.locale('en-us')
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
expect(result.locale).toBe('en-us');
// Variant should work with locale
});
});

describe('Variant Error Handling', () => {
it('should handle variant queries with reasonable performance', async () => {
const startTime = Date.now();

const result = await stack.contentType(contentTypeUid).entry()
.variants(variantUid)
.limit(10)
.find<{ entries: TEntry[] }>();

const endTime = Date.now();
const duration = endTime - startTime;

expect(result).toBeDefined();
expect(result.entries).toBeDefined();
expect(duration).toBeLessThan(10000); // Should complete within 10 seconds

if (result.entries && result.entries.length > 0) {
const entry = result.entries[0] as any;
expect(entry.uid).toBeDefined();
}
});

it('should handle repeated variant requests consistently', async () => {
// First request
const result1 = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.fetch<TEntry>();

// Second request
const result2 = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.fetch<TEntry>();

expect(result1).toBeDefined();
expect(result2).toBeDefined();
expect(result1.uid).toBe(result2.uid);

// Both requests should return consistent data
expect(result1.uid).toBe(entryUid);
expect(result2.uid).toBe(entryUid);
});
});

describe('Advanced Variant Error Handling', () => {
it('should handle invalid variant UIDs gracefully', async () => {
try {
await stack.contentType(contentTypeUid).entry(entryUid)
.variants('invalid_variant_uid')
.fetch<TEntry>();
} catch (error) {
expect(error).toBeDefined();
// Should return meaningful error message
}
});

it('should handle basic variant requests', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Variant header should be applied
});

it('should handle variant query errors gracefully', async () => {
try {
await stack.contentType('invalid_content_type').entry()
.variants(variantUid)
.find<{ entries: TEntry[] }>();
} catch (error) {
expect(error).toBeDefined();
// Should handle error gracefully
}
});
});

describe('Variant Integration Tests', () => {
it('should support variant with reference inclusion', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.includeReference()
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
// Reference inclusion should work with variants
});

it('should handle variant with locale specification', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.locale('en-us')
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
expect(result.locale).toBe('en-us');
// Variant should work with locale
});

it('should support variant with field selection', async () => {
const result = await stack.contentType(contentTypeUid).entry(entryUid)
.variants(variantUid)
.only(['title', 'uid'])
.fetch<TEntry>();

expect(result).toBeDefined();
expect(result.uid).toBe(entryUid);
expect(result.title).toBeDefined();
// Only specified fields should be returned with variant
});
});
});
Loading