From b2586f3bf19195008c6715893e1e886fb82eeabf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 16:09:40 +0000 Subject: [PATCH 1/5] Initial plan From bf5d2ab173e5e339d155eba1a45879f23782fcc4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 16:16:34 +0000 Subject: [PATCH 2/5] Add MetaDetails entity and update MediaAttachment meta properties Co-authored-by: abraham <3341+abraham@users.noreply.github.com> --- dist/schema.json | 74 +++++++++++++++++++ .../parsers/EntityParser.draft.test.ts | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/dist/schema.json b/dist/schema.json index 6ea7f8a..9726923 100644 --- a/dist/schema.json +++ b/dist/schema.json @@ -35204,6 +35204,28 @@ "x", "y" ] + }, + "small": { + "description": "Details about the small preview version of the attachment.", + "oneOf": [ + { + "$ref": "#/components/schemas/MetaDetails" + }, + { + "type": "null" + } + ] + }, + "original": { + "description": "Details about the original version of the attachment.", + "oneOf": [ + { + "$ref": "#/components/schemas/MetaDetails" + }, + { + "type": "null" + } + ] } } }, @@ -35241,6 +35263,58 @@ "description": "Official Mastodon API documentation" } }, + "MetaDetails": { + "type": "object", + "description": "Metadata details about a media attachment.", + "properties": { + "aspect": { + "description": "The media aspect ratio of the video or image attachment.", + "type": [ + "number", + "null" + ] + }, + "bitrate": { + "description": "The media bitrate of the video or audio attachment.", + "type": [ + "integer", + "null" + ] + }, + "duration": { + "description": "The duration of the video attachment.", + "type": [ + "number", + "null" + ] + }, + "frame_rate": { + "description": "The frame rate of the video attachment.", + "type": [ + "string", + "null" + ] + }, + "height": { + "description": "The height of the attachment in pixels.", + "type": [ + "integer", + "null" + ] + }, + "width": { + "description": "The width of the attachment in pixels.", + "type": [ + "integer", + "null" + ] + } + }, + "externalDocs": { + "url": "https://docs.joinmastodon.org/entities/MetaDetails/#attributes", + "description": "Official Mastodon API documentation" + } + }, "Notification": { "type": "object", "description": "Represents a notification of an event relevant to the user.", diff --git a/src/__tests__/parsers/EntityParser.draft.test.ts b/src/__tests__/parsers/EntityParser.draft.test.ts index e1bd554..e353ed3 100644 --- a/src/__tests__/parsers/EntityParser.draft.test.ts +++ b/src/__tests__/parsers/EntityParser.draft.test.ts @@ -40,6 +40,6 @@ describe('EntityParser - Draft File Handling', () => { // This test validates that only explicit draft: true is filtered // This is implicitly tested by checking that we still get a reasonable number of entities const entities = parser.parseAllEntities(); - expect(entities.length).toBe(91); // Exact count after removing EncryptedMessage and entities from blocked files (increased due to extracted nested entities + Admin::DimensionData + DiscoverOauthServerConfigurationResponse + OEmbedResponse) + expect(entities.length).toBe(92); // Exact count after removing EncryptedMessage and entities from blocked files (increased due to extracted nested entities + Admin::DimensionData + DiscoverOauthServerConfigurationResponse + OEmbedResponse + MetaDetails) }); }); From 875e4d1df91d9d3d9d78c6cc4880a27e85e15021 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 16:19:38 +0000 Subject: [PATCH 3/5] Add comprehensive tests for MetaDetails entity parsing Co-authored-by: abraham <3341+abraham@users.noreply.github.com> --- .../parsers/EntityParser.metadetails.test.ts | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/__tests__/parsers/EntityParser.metadetails.test.ts diff --git a/src/__tests__/parsers/EntityParser.metadetails.test.ts b/src/__tests__/parsers/EntityParser.metadetails.test.ts new file mode 100644 index 0000000..e672e7c --- /dev/null +++ b/src/__tests__/parsers/EntityParser.metadetails.test.ts @@ -0,0 +1,90 @@ +import { EntityParser } from '../../parsers/EntityParser'; + +describe('EntityParser - MetaDetails Entity', () => { + let parser: EntityParser; + + beforeEach(() => { + parser = new EntityParser(); + }); + + test('should parse MetaDetails entity', () => { + const entities = parser.parseAllEntities(); + const metaDetails = entities.find((e) => e.name === 'MetaDetails'); + + expect(metaDetails).toBeDefined(); + expect(metaDetails?.description).toBe( + 'Metadata details about a media attachment.' + ); + }); + + test('MetaDetails should have all required properties', () => { + const entities = parser.parseAllEntities(); + const metaDetails = entities.find((e) => e.name === 'MetaDetails'); + + expect(metaDetails).toBeDefined(); + expect(metaDetails?.attributes).toBeDefined(); + + const attributeNames = metaDetails?.attributes.map((attr) => attr.name); + expect(attributeNames).toContain('width'); + expect(attributeNames).toContain('height'); + expect(attributeNames).toContain('frame_rate'); + expect(attributeNames).toContain('duration'); + expect(attributeNames).toContain('bitrate'); + expect(attributeNames).toContain('aspect'); + }); + + test('MetaDetails properties should be nullable', () => { + const entities = parser.parseAllEntities(); + const metaDetails = entities.find((e) => e.name === 'MetaDetails'); + + expect(metaDetails).toBeDefined(); + expect(metaDetails?.attributes).toBeDefined(); + + // All properties should be nullable + metaDetails?.attributes.forEach((attr) => { + expect(attr.nullable).toBe(true); + }); + }); + + test('MediaAttachment should have meta[small] and meta[original] properties', () => { + const entities = parser.parseAllEntities(); + const mediaAttachment = entities.find((e) => e.name === 'MediaAttachment'); + + expect(mediaAttachment).toBeDefined(); + expect(mediaAttachment?.attributes).toBeDefined(); + + const attributeNames = mediaAttachment?.attributes.map((attr) => attr.name); + expect(attributeNames).toContain('meta[small]'); + expect(attributeNames).toContain('meta[original]'); + }); + + test('MediaAttachment meta[small] should reference MetaDetails', () => { + const entities = parser.parseAllEntities(); + const mediaAttachment = entities.find((e) => e.name === 'MediaAttachment'); + + expect(mediaAttachment).toBeDefined(); + + const metaSmall = mediaAttachment?.attributes.find( + (attr) => attr.name === 'meta[small]' + ); + expect(metaSmall).toBeDefined(); + expect(metaSmall?.type).toContain('MetaDetails'); + expect(metaSmall?.optional).toBe(true); + expect(metaSmall?.nullable).toBe(true); + }); + + test('MediaAttachment meta[original] should reference MetaDetails', () => { + const entities = parser.parseAllEntities(); + const mediaAttachment = entities.find((e) => e.name === 'MediaAttachment'); + + expect(mediaAttachment).toBeDefined(); + + const metaOriginal = mediaAttachment?.attributes.find( + (attr) => attr.name === 'meta[original]' + ); + expect(metaOriginal).toBeDefined(); + expect(metaOriginal?.type).toContain('MetaDetails'); + expect(metaOriginal?.optional).toBe(true); + expect(metaOriginal?.nullable).toBe(true); + }); +}); From ff85210d4358c6363e6d3143e4918d99c3f53a99 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 16:21:52 +0000 Subject: [PATCH 4/5] Optimize MetaDetails tests to parse entities once for better performance Co-authored-by: abraham <3341+abraham@users.noreply.github.com> --- .../parsers/EntityParser.metadetails.test.ts | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/__tests__/parsers/EntityParser.metadetails.test.ts b/src/__tests__/parsers/EntityParser.metadetails.test.ts index e672e7c..a55f960 100644 --- a/src/__tests__/parsers/EntityParser.metadetails.test.ts +++ b/src/__tests__/parsers/EntityParser.metadetails.test.ts @@ -1,14 +1,15 @@ import { EntityParser } from '../../parsers/EntityParser'; +import { EntityClass } from '../../interfaces/EntityClass'; describe('EntityParser - MetaDetails Entity', () => { - let parser: EntityParser; + let entities: EntityClass[]; - beforeEach(() => { - parser = new EntityParser(); + beforeAll(() => { + const parser = new EntityParser(); + entities = parser.parseAllEntities(); }); test('should parse MetaDetails entity', () => { - const entities = parser.parseAllEntities(); const metaDetails = entities.find((e) => e.name === 'MetaDetails'); expect(metaDetails).toBeDefined(); @@ -18,7 +19,6 @@ describe('EntityParser - MetaDetails Entity', () => { }); test('MetaDetails should have all required properties', () => { - const entities = parser.parseAllEntities(); const metaDetails = entities.find((e) => e.name === 'MetaDetails'); expect(metaDetails).toBeDefined(); @@ -34,7 +34,6 @@ describe('EntityParser - MetaDetails Entity', () => { }); test('MetaDetails properties should be nullable', () => { - const entities = parser.parseAllEntities(); const metaDetails = entities.find((e) => e.name === 'MetaDetails'); expect(metaDetails).toBeDefined(); @@ -47,7 +46,6 @@ describe('EntityParser - MetaDetails Entity', () => { }); test('MediaAttachment should have meta[small] and meta[original] properties', () => { - const entities = parser.parseAllEntities(); const mediaAttachment = entities.find((e) => e.name === 'MediaAttachment'); expect(mediaAttachment).toBeDefined(); @@ -59,7 +57,6 @@ describe('EntityParser - MetaDetails Entity', () => { }); test('MediaAttachment meta[small] should reference MetaDetails', () => { - const entities = parser.parseAllEntities(); const mediaAttachment = entities.find((e) => e.name === 'MediaAttachment'); expect(mediaAttachment).toBeDefined(); @@ -74,7 +71,6 @@ describe('EntityParser - MetaDetails Entity', () => { }); test('MediaAttachment meta[original] should reference MetaDetails', () => { - const entities = parser.parseAllEntities(); const mediaAttachment = entities.find((e) => e.name === 'MediaAttachment'); expect(mediaAttachment).toBeDefined(); From d265128ff666d4d56a794efcc1b655ba1132346f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 16:23:11 +0000 Subject: [PATCH 5/5] Remove unnecessary EntityClass import in MetaDetails tests Co-authored-by: abraham <3341+abraham@users.noreply.github.com> --- src/__tests__/parsers/EntityParser.metadetails.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/__tests__/parsers/EntityParser.metadetails.test.ts b/src/__tests__/parsers/EntityParser.metadetails.test.ts index a55f960..3c1d40e 100644 --- a/src/__tests__/parsers/EntityParser.metadetails.test.ts +++ b/src/__tests__/parsers/EntityParser.metadetails.test.ts @@ -1,8 +1,7 @@ import { EntityParser } from '../../parsers/EntityParser'; -import { EntityClass } from '../../interfaces/EntityClass'; describe('EntityParser - MetaDetails Entity', () => { - let entities: EntityClass[]; + let entities: ReturnType; beforeAll(() => { const parser = new EntityParser();