Skip to content
New issue

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

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

Already on GitHub? # to your account

adding or removing values from or into an array and then calling get returns _Map<String, dynamic> #834

Closed
4 tasks done
Nidal-Bakir opened this issue Mar 1, 2023 · 6 comments
Labels
type:bug Impaired feature or lacking behavior that is likely assumed

Comments

@Nidal-Bakir
Copy link
Member

Nidal-Bakir commented Mar 1, 2023

New Issue Checklist

Issue Description

Adding or removing values from or into an array using (setAdd, setAddAll, setAddUnique, setAddAllUnique, setRemove, setRemoveAll) in ParseObject and then calling get returns _Map<String, dynamic>

related to: #696, #842

Steps to reproduce

  1. create ParseObject
  2. add a value to an array using setAdd function for example
  3. get the array using the array key with get("key")
  4. the result of calling get("key") is Map which is not expected

code snippet:

final dietPlansObject = ParseObject("Diet_Plans");

dietPlansObject.setAdd("arrayKey", 1);

final array = dietPlansObject.get("arrayKey");

print(array.runtimeType); // _Map<String, dynamic>

Actual Outcome

_Map<String, dynamic>

Expected Outcome

An Iterable that contains all the added values and does not contain the removed ones

Environment

Parse Flutter SDK

  • SDK version: 3.1.15
  • Operating system version: any

Server

  • Parse Server version: any

Logs

type '_Map<String, dynamic>' is not a subtype of type 'List?' in type cast
package:parse_server_sdk/src/objects/parse_base.dart 223:36 ParseBase.get
test/src/objects/parse_object_test.dart 711:39 main...
parse_object_test.dart:711

@parse-github-assistant
Copy link

parse-github-assistant bot commented Mar 1, 2023

Thanks for opening this issue!

  • 🚀 You can help us to fix this issue faster by opening a pull request with a failing test. See our Contribution Guide for how to make a pull request, or read our New Contributor's Guide if this is your first time contributing.

@Nidal-Bakir
Copy link
Member Author

Nidal-Bakir commented Mar 1, 2023

I just find it out while writing tests for ParseObject class.

I have written all the tests to make sure that will not happen again. we just need to fix it. I will open a new PR to attempt to fix this after this PR #805 is merged.

Tests
group('Array', () {
    const keyArray = 'array';

    late ParseObject dietPlansObject;

    setUp(() {
      dietPlansObject = ParseObject("Diet_Plans", client: client);
    });

    test(
        'adding values using setAdd() and then calling get(keyArray) '
        'should return Instance of Iterable that contains all the added values ',
        () {
      // act
      dietPlansObject.setAdd(keyArray, 1);
      dietPlansObject.setAdd(keyArray, 2);
      dietPlansObject.setAdd(keyArray, 1);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 1],
        ),
        isTrue,
      );
    });

    test(
        'adding values using setAddAll() and then calling get(keyArray) '
        'should return Instance of Iterable that contains all the added values',
        () {
      // act
      dietPlansObject.setAddAll(keyArray, [1, 2, 1]);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 1],
        ),
        isTrue,
      );
    });

    test(
        'adding values using setAddUnique() and then calling get(keyArray) '
        'should return Instance of Iterable that contains all the added values'
        ' with out any duplication in the values', () {
      // act
      dietPlansObject.setAddUnique(keyArray, 1);
      dietPlansObject.setAddUnique(keyArray, 2);
      dietPlansObject.setAddUnique(keyArray, 1);
      dietPlansObject.setAddUnique(keyArray, 3);
      dietPlansObject.setAddUnique(keyArray, 1);
      dietPlansObject.setAddUnique(keyArray, 4);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 3, 4],
        ),
        isTrue,
      );
    });

    test(
        'adding values using setAddAllUnique() and then calling get(keyArray) '
        'should return Instance of Iterable that contains all the added values'
        ' with out any duplication in the values', () {
      // act
      dietPlansObject.setAddAllUnique(keyArray, [1, 2, 1, 3, 1, 4, 1]);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 3, 4],
        ),
        isTrue,
      );
    });

    test(
        'removing values using setRemove() and then calling get(keyArray) '
        'should return Instance of Iterable that NOT contains the removed values',
        () {
      // arrange
      final resultFromServer = {
        "objectId": "O6BHlwV48Z",
        "createdAt": "2023-02-26T13:23:03.073Z",
        "updatedAt": "2023-03-01T03:38:16.390Z",
        keyArray: [1, 2, 3, 4],
      };

      dietPlansObject = ParseObject('Diet_Plans')
        ..fromJson(
          resultFromServer,
        );

      // act
      dietPlansObject.setRemove(keyArray, 4);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 3],
        ),
        isTrue,
      );
    });

    test(
        'removing values using setRemoveAll() and then calling get(keyArray) '
        'should return Instance of Iterable that NOT contains the removed values',
        () {
      // arrange
      final resultFromServer = {
        "objectId": "O6BHlwV48Z",
        "createdAt": "2023-02-26T13:23:03.073Z",
        "updatedAt": "2023-03-01T03:38:16.390Z",
        keyArray: [1, 2, 3, 4],
      };

      dietPlansObject = ParseObject('Diet_Plans')
        ..fromJson(
          resultFromServer,
        );

      // act
      dietPlansObject.setRemoveAll(keyArray, [3, 4]);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2],
        ),
        isTrue,
      );
    });

    test(
        'the array should not been affected by removing non existent '
        'values using setRemove()', () {
      // arrange
      final resultFromServer = {
        "objectId": "O6BHlwV48Z",
        "createdAt": "2023-02-26T13:23:03.073Z",
        "updatedAt": "2023-03-01T03:38:16.390Z",
        keyArray: [1, 2, 3, 4],
      };

      dietPlansObject = ParseObject('Diet_Plans')
        ..fromJson(
          resultFromServer,
        );

      // act
      dietPlansObject.setRemove(keyArray, 15);
      dietPlansObject.setRemove(keyArray, 16);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 3, 4],
        ),
        isTrue,
      );
    });

    test(
        'the array should not been affected by removing non existent '
        'values using setRemoveAll()', () {
      // arrange
      final resultFromServer = {
        "objectId": "O6BHlwV48Z",
        "createdAt": "2023-02-26T13:23:03.073Z",
        "updatedAt": "2023-03-01T03:38:16.390Z",
        keyArray: [1, 2, 3, 4],
      };

      dietPlansObject = ParseObject('Diet_Plans')
        ..fromJson(
          resultFromServer,
        );

      // act
      dietPlansObject.setRemoveAll(keyArray, [15, 16]);

      // assert
      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2, 3, 4],
        ),
        isTrue,
      );
    });

    test(
        'adding to an array and then removing from it should result in error '
        'the user can not add and remove in the same time', () {
      // act
      dietPlansObject.setAdd(keyArray, 1);
      dietPlansObject.setAdd(keyArray, 2);

      // assert
      expect(
        () => dietPlansObject.setRemove(keyArray, 2),
        throwsA(isA<String>()),
      );

      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2],
        ),
        isTrue,
      );
    });

    test(
        'removing from an array and then adding to it should result in error '
        'the user can not remove and add in the same time', () {
      // arrange
      final resultFromServer = {
        "objectId": "O6BHlwV48Z",
        "createdAt": "2023-02-26T13:23:03.073Z",
        "updatedAt": "2023-03-01T03:38:16.390Z",
        keyArray: [1, 2, 3, 4],
      };

      dietPlansObject = ParseObject('Diet_Plans')
        ..fromJson(
          resultFromServer,
        );

      // act
      dietPlansObject.setRemove(keyArray, 4);
      dietPlansObject.setRemove(keyArray, 3);

      // assert
      expect(
        () => dietPlansObject.setAdd(keyArray, 5),
        throwsA(isA<String>()),
      );

      final array = dietPlansObject.get(keyArray);

      expect(array, isA<Iterable>());

      expect(
        DeepCollectionEquality.unordered().equals(
          array,
          [1, 2],
        ),
        isTrue,
      );
    });
  });

@mtrezza
Copy link
Member

mtrezza commented Mar 1, 2023

Thanks @Nidal-Bakir; you've been quite active recently, would you be interested in joining the Parse Flutter SDK review team? You'll get notified when there's a review request for PRs.

@mtrezza mtrezza added the type:bug Impaired feature or lacking behavior that is likely assumed label Mar 1, 2023
@Nidal-Bakir
Copy link
Member Author

Thank you for the offer, @mtrezza I would be honored to join the Parse Flutter SDK review team and contribute to the development of the SDK.

@mtrezza
Copy link
Member

mtrezza commented Mar 2, 2023

Great, you'll receive an invitation shortly

@Nidal-Bakir
Copy link
Member Author

Fix via #860

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
type:bug Impaired feature or lacking behavior that is likely assumed
Projects
None yet
Development

No branches or pull requests

2 participants