def testExplicitShareOrderMigration(self):
    """Ensure that the EXPLICIT_SHARE_ORDER migration works correctly.
    The expectation is that the migration orders the episode ids and photo ids to the
    original mobile client algorithm for cover photo selection.
    """
    def _IsEpDictOrderedAsOriginalAlgorithm(ep_dicts, episode_id_key):
      """Returns true if the order matches original mobile client algorithm ordering for
      cover photo selection."""
      last_episode_id = None
      for ep_dict in ep_dicts:
        # Episodes should be greatest (earliest) first.
        if last_episode_id is not None and ep_dict[episode_id_key] >= last_episode_id:
          return False
        last_episode_id = ep_dict[episode_id_key]
        # Now, loop through the photos in this episode.
        last_photo_id = None
        for photo_id in ep_dict['photo_ids']:
          # Photo Ids should be least (oldest) first.
          if last_photo_id is not None and photo_id <= last_photo_id:
            return False
          last_photo_id = photo_id
      # Nothing out of order found.
      return True

    def _ConstructEpDict():
      """Create some ep_dicts for sharing."""
      # Create 2 episodes with 2 photos each.
      episode_id1, photo_ids1 = self._UploadOneEpisode(self._cookie, 2)
      episode_id2, photo_ids2 = self._UploadOneEpisode(self._cookie, 2)

      ep_dicts = self._tester._CreateCopyDictList(self._cookie,
                                                 [(episode_id1, photo_ids1),
                                                  (episode_id2, photo_ids2)])

      # Order the episodes and photos so that the migration will need to change it.
      # This is the opposite of the original client algorithm for cover photo selection.
      ep_dicts = sorted(ep_dicts, key=lambda e: e['new_episode_id'])
      for episode in ep_dicts:
        episode['photo_ids'] = sorted(episode['photo_ids'], reverse=True)

      # Assert that these are not ordered according to the original client algorithm for cover photo selection.
      self.assertFalse(_IsEpDictOrderedAsOriginalAlgorithm(ep_dicts, 'new_episode_id'),
                       'Should not be correctly ordered at this point')

      return ep_dicts

    # Generate a couple of ep_dicts to share.
    ep_dicts1 = _ConstructEpDict()
    ep_dicts2 = _ConstructEpDict()

    # Do a share_new.
    request_dict = {'activity': self._tester.CreateActivityDict(self._cookie),
                    'viewpoint': self._CreateViewpointDict(self._cookie),
                    'episodes': ep_dicts1,
                    'contacts': self._tester.CreateContactDicts([self._user2.user_id, self._user3.user_id])}
    self._SendRequest('share_new', self._cookie, request_dict, version=Message.INLINE_COMMENTS)

    # Now, do a share_existing.
    request_dict = {'activity': self._tester.CreateActivityDict(self._cookie),
                    'viewpoint_id': request_dict['viewpoint']['viewpoint_id'],
                    'episodes': ep_dicts2}
    self._SendRequest('share_existing', self._cookie, request_dict, version=Message.INLINE_COMMENTS)

    # Query the activities to see what order the episode_ids and photo_ids were persisted in.
    activities = self._RunAsync(Activity.RangeQuery,
                                      self._client,
                                      request_dict['viewpoint_id'],
                                      range_desc=None,
                                      limit=50,
                                      col_names=None,
                                      scan_forward=False)

    # Check that the order of episode ids and photo ids is consistent with the original mobile client
    # algorithm for cover photo selection.  This demonstrates that the migration happened.
    for activity in activities:
      # Note this is only valid for share_new and share_existing activities, but that's all we should have
      # as this point.
      args_dict = json.loads(activity.json)
      self.assertTrue(_IsEpDictOrderedAsOriginalAlgorithm(args_dict['episodes'], 'episode_id'),
                       'Should be correctly ordered at this point')
dataset/ETHPy150Open viewfinderco/viewfinder/backend/www/test/versioning_test.py/VersioningTestCase.testExplicitShareOrderMigration/original