FindOneAndReplaceFunctionalTest.php 6.26 KB
Newer Older
1 2 3 4 5
<?php

namespace MongoDB\Tests\Collection\CrudSpec;

use MongoDB\Collection;
6
use MongoDB\Operation\FindOneAndReplace;
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23

/**
 * CRUD spec functional tests for findOneAndReplace().
 *
 * @see https://github.com/mongodb/specifications/tree/master/source/crud/tests
 */
class FindOneAndReplaceFunctionalTest extends FunctionalTestCase
{
    public function setUp()
    {
        parent::setUp();

        $this->createFixtures(3);
    }

    public function testFindOneAndReplaceWhenManyDocumentsMatchReturningDocumentBeforeModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
24 25 26 27 28 29
        $filter = ['_id' => ['$gt' => 1]];
        $replacement = ['x' => 32];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
        ];
30 31

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
Jeremy Mikola's avatar
Jeremy Mikola committed
32
        $this->assertSameDocument(['x' => 22], $document);
33

Jeremy Mikola's avatar
Jeremy Mikola committed
34 35 36 37 38
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 32],
            ['_id' => 3, 'x' => 33],
        ];
39

40
        $this->assertSameDocuments($expected, $this->collection->find());
41 42 43 44
    }

    public function testFindOneAndReplaceWhenManyDocumentsMatchReturningDocumentAfterModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
45 46 47 48 49
        $filter = ['_id' => ['$gt' => 1]];
        $replacement = ['x' => 32];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
50
            'returnDocument' => FindOneAndReplace::RETURN_DOCUMENT_AFTER,
Jeremy Mikola's avatar
Jeremy Mikola committed
51
        ];
52 53

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
Jeremy Mikola's avatar
Jeremy Mikola committed
54
        $this->assertSameDocument(['x' => 32], $document);
55

Jeremy Mikola's avatar
Jeremy Mikola committed
56 57 58 59 60
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 32],
            ['_id' => 3, 'x' => 33],
        ];
61

62
        $this->assertSameDocuments($expected, $this->collection->find());
63 64 65 66
    }

    public function testFindOneAndReplaceWhenOneDocumentMatchesReturningDocumentBeforeModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
67 68 69 70 71 72
        $filter = ['_id' => 2];
        $replacement = ['x' => 32];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
        ];
73 74

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
Jeremy Mikola's avatar
Jeremy Mikola committed
75
        $this->assertSameDocument(['x' => 22], $document);
76

Jeremy Mikola's avatar
Jeremy Mikola committed
77 78 79 80 81
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 32],
            ['_id' => 3, 'x' => 33],
        ];
82

83
        $this->assertSameDocuments($expected, $this->collection->find());
84 85 86 87
    }

    public function testFindOneAndReplaceWhenOneDocumentMatchesReturningDocumentAfterModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
88 89 90 91 92
        $filter = ['_id' => 2];
        $replacement = ['x' => 32];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
93
            'returnDocument' => FindOneAndReplace::RETURN_DOCUMENT_AFTER,
Jeremy Mikola's avatar
Jeremy Mikola committed
94
        ];
95 96

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
Jeremy Mikola's avatar
Jeremy Mikola committed
97
        $this->assertSameDocument(['x' => 32], $document);
98

Jeremy Mikola's avatar
Jeremy Mikola committed
99 100 101 102 103
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 32],
            ['_id' => 3, 'x' => 33],
        ];
104

105
        $this->assertSameDocuments($expected, $this->collection->find());
106 107 108 109
    }

    public function testFindOneAndReplaceWhenNoDocumentsMatchReturningDocumentBeforeModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
110 111 112 113 114 115
        $filter = ['_id' => 4];
        $replacement = ['x' => 44];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
        ];
116 117 118 119

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
        $this->assertNull($document);

Jeremy Mikola's avatar
Jeremy Mikola committed
120 121 122 123 124
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 22],
            ['_id' => 3, 'x' => 33],
        ];
125

126
        $this->assertSameDocuments($expected, $this->collection->find());
127 128 129 130
    }

    public function testFindOneAndReplaceWithUpsertWhenNoDocumentsMatchReturningDocumentBeforeModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
131
        $filter = ['_id' => 4];
132
        // Server 2.4 and earlier requires any custom ID to also be in the replacement document
Jeremy Mikola's avatar
Jeremy Mikola committed
133 134 135 136
        $replacement = ['_id' => 4, 'x' => 44];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
137
            'upsert' => true,
Jeremy Mikola's avatar
Jeremy Mikola committed
138
        ];
139 140 141 142

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
        $this->assertNull($document);

Jeremy Mikola's avatar
Jeremy Mikola committed
143 144 145 146 147 148
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 22],
            ['_id' => 3, 'x' => 33],
            ['_id' => 4, 'x' => 44],
        ];
149

150
        $this->assertSameDocuments($expected, $this->collection->find());
151 152 153 154
    }

    public function testFindOneAndReplaceWhenNoDocumentsMatchReturningDocumentAfterModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
155 156 157 158 159
        $filter = ['_id' => 4];
        $replacement = ['x' => 44];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
160
            'returnDocument' => FindOneAndReplace::RETURN_DOCUMENT_AFTER,
Jeremy Mikola's avatar
Jeremy Mikola committed
161
        ];
162 163 164 165

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
        $this->assertNull($document);

Jeremy Mikola's avatar
Jeremy Mikola committed
166 167 168 169 170
        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 22],
            ['_id' => 3, 'x' => 33],
        ];
171

172
        $this->assertSameDocuments($expected, $this->collection->find());
173 174 175 176
    }

    public function testFindOneAndReplaceWithUpsertWhenNoDocumentsMatchReturningDocumentAfterModification()
    {
Jeremy Mikola's avatar
Jeremy Mikola committed
177
        $filter = ['_id' => 4];
178
        // Server 2.4 and earlier requires any custom ID to also be in the replacement document
Jeremy Mikola's avatar
Jeremy Mikola committed
179 180 181 182
        $replacement = ['_id' => 4, 'x' => 44];
        $options = [
            'projection' => ['x' => 1, '_id' => 0],
            'sort' => ['x' => 1],
183
            'returnDocument' => FindOneAndReplace::RETURN_DOCUMENT_AFTER,
184
            'upsert' => true,
Jeremy Mikola's avatar
Jeremy Mikola committed
185
        ];
186 187

        $document = $this->collection->findOneAndReplace($filter, $replacement, $options);
Jeremy Mikola's avatar
Jeremy Mikola committed
188 189 190 191 192 193 194 195
        $this->assertSameDocument(['x' => 44], $document);

        $expected = [
            ['_id' => 1, 'x' => 11],
            ['_id' => 2, 'x' => 22],
            ['_id' => 3, 'x' => 33],
            ['_id' => 4, 'x' => 44],
        ];
196

197
        $this->assertSameDocuments($expected, $this->collection->find());
198 199
    }
}