Maintain local ⭤ remote in sync with automatic AT Protocol parity for Laravel (alpha & unstable)
1<?php
2
3namespace SocialDept\AtpParity\Tests\Unit;
4
5use SocialDept\AtpParity\Support\SchemaMapper;
6use SocialDept\AtpParity\Tests\Fixtures\TestModel;
7use SocialDept\AtpParity\Tests\Fixtures\TestRecord;
8use SocialDept\AtpParity\Tests\TestCase;
9
10class SchemaMapperTest extends TestCase
11{
12 public function test_record_class_returns_schema_class(): void
13 {
14 $mapper = new SchemaMapper(
15 schemaClass: TestRecord::class,
16 modelClass: TestModel::class,
17 toAttributes: fn () => [],
18 toRecordData: fn () => [],
19 );
20
21 $this->assertSame(TestRecord::class, $mapper->recordClass());
22 }
23
24 public function test_model_class_returns_model_class(): void
25 {
26 $mapper = new SchemaMapper(
27 schemaClass: TestRecord::class,
28 modelClass: TestModel::class,
29 toAttributes: fn () => [],
30 toRecordData: fn () => [],
31 );
32
33 $this->assertSame(TestModel::class, $mapper->modelClass());
34 }
35
36 public function test_lexicon_returns_schema_lexicon(): void
37 {
38 $mapper = new SchemaMapper(
39 schemaClass: TestRecord::class,
40 modelClass: TestModel::class,
41 toAttributes: fn () => [],
42 toRecordData: fn () => [],
43 );
44
45 $this->assertSame('app.test.record', $mapper->lexicon());
46 }
47
48 public function test_to_model_invokes_to_attributes_closure(): void
49 {
50 $closureCalled = false;
51
52 $mapper = new SchemaMapper(
53 schemaClass: TestRecord::class,
54 modelClass: TestModel::class,
55 toAttributes: function (TestRecord $record) use (&$closureCalled) {
56 $closureCalled = true;
57
58 return ['content' => $record->text.'_transformed'];
59 },
60 toRecordData: fn () => [],
61 );
62
63 $record = new TestRecord(text: 'original');
64 $model = $mapper->toModel($record);
65
66 $this->assertTrue($closureCalled);
67 $this->assertSame('original_transformed', $model->content);
68 }
69
70 public function test_to_record_invokes_to_record_data_closure(): void
71 {
72 $closureCalled = false;
73
74 $mapper = new SchemaMapper(
75 schemaClass: TestRecord::class,
76 modelClass: TestModel::class,
77 toAttributes: fn () => [],
78 toRecordData: function (TestModel $model) use (&$closureCalled) {
79 $closureCalled = true;
80
81 return ['text' => strtoupper($model->content)];
82 },
83 );
84
85 $model = new TestModel(['content' => 'hello']);
86 $record = $mapper->toRecord($model);
87
88 $this->assertTrue($closureCalled);
89 $this->assertSame('HELLO', $record->text);
90 }
91
92 public function test_closures_receive_correct_types(): void
93 {
94 $receivedRecordType = null;
95 $receivedModelType = null;
96
97 $mapper = new SchemaMapper(
98 schemaClass: TestRecord::class,
99 modelClass: TestModel::class,
100 toAttributes: function ($record) use (&$receivedRecordType) {
101 $receivedRecordType = get_class($record);
102
103 return ['content' => $record->text];
104 },
105 toRecordData: function ($model) use (&$receivedModelType) {
106 $receivedModelType = get_class($model);
107
108 return ['text' => $model->content];
109 },
110 );
111
112 $mapper->toModel(new TestRecord(text: 'test'));
113 $mapper->toRecord(new TestModel(['content' => 'test']));
114
115 $this->assertSame(TestRecord::class, $receivedRecordType);
116 $this->assertSame(TestModel::class, $receivedModelType);
117 }
118
119 public function test_upsert_works_with_schema_mapper(): void
120 {
121 $mapper = new SchemaMapper(
122 schemaClass: TestRecord::class,
123 modelClass: TestModel::class,
124 toAttributes: fn (TestRecord $r) => ['content' => $r->text],
125 toRecordData: fn (TestModel $m) => ['text' => $m->content],
126 );
127
128 $record = new TestRecord(text: 'schema mapper test');
129 $meta = ['uri' => 'at://test/col/rkey', 'cid' => 'cid123'];
130
131 $model = $mapper->upsert($record, $meta);
132
133 $this->assertTrue($model->exists);
134 $this->assertSame('schema mapper test', $model->content);
135 $this->assertSame('at://test/col/rkey', $model->atp_uri);
136 }
137}