<commit_before>/*!
 * Copyright 2013 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

var _ = require('underscore');
var assert = require('assert');

var ActivityConstants = require('oae-activity/lib/constants').ActivityConstants;
var ActivityDAO = require('oae-activity/lib/internal/dao');

var RestAPI = require('oae-rest');
var TestsUtil = require('oae-tests');

describe('Activity Migration', function() {

    // Rest context that can be used every time we need to make a request as a tenant admin
    var camAdminRestContext = null;


    /**
     * Function that will fill up the rest context(s)
     */
    before(function(callback) {
        camAdminRestContext = TestsUtil.createTenantAdminRestContext(global.oaeTests.tenants.cam.host);
        return callback();
    });

    /**
     * Mocks an activity
     *
     * @param  {String}     activityId      The ID to use for the activity
     * @param  {String}     userId          The ID of the user that will be the actor of this activity
     * @return {Activity}                   A mocked activity
     */
    var _mockActivity = function(activityId, userId) {
        var activity = {};
        activity[ActivityConstants.properties.OAE_ACTIVITY_TYPE] = 'content-create';
        activity[ActivityConstants.properties.OAE_ACTIVITY_ID] = activityId;
        activity.verb = 'created';
        activity.published = Date.now();

        activity.actor = {
            'objectType': 'user',
            'oae:id': userId
        };
        return activity;
    };

    /**
     * Creates 10 activities, 5 under the old `userId` activity stream ID and 5 under the new `userId#activity` activity stream
     *
     * @param  {String}     userId          The ID of the user for which to store the activitites
     * @param  {Function}   callback        Standard callback function
     * @param  {Object}     callback.err    Standard error object
     */
    var setUp = function(userId, callback) {
        var activities = {};

        // Generate 5 activities under the `u:cam:foo` activity stream
        activities[userId] = {};
        for (var i = 0; i < 5; i++) {
            var oldActivityId = Date.now() + ':' + i;
            activities[userId][oldActivityId] = _mockActivity(oldActivityId, userId);
        }

        // Generate 5 activitities under the `u:cam:foo#activity` activity stream
        activities[userId + '#activity'] = {};
        for (i = 5; i < 10; i++) {
            var newActivityId = Date.now() + ':' + i;
            activities[userId + '#activity'][newActivityId] = _mockActivity(newActivityId, userId);
        }

        ActivityDAO.deliverActivities(activities, callback);
    };

    /**
     * Test that verifies that activities are automatically fetched from both activity streams
     */
    it('verify mixed activity streams can be retrieved', function(callback) {
        TestsUtil.generateTestUsers(camAdminRestContext, 1, function(err, users) {
            assert.ok(!err);

            var mrvisser = _.values(users)[0];
            setUp(mrvisser.user.id, function(activities) {
                assert.ok(!err);

                // Get the 4 first results, these should come from the `userId#activity` stream
                RestAPI.Activity.getCurrentUserActivityStream(mrvisser.restContext, {'limit': 4}, function(err, activityStream) {
                    assert.ok(!err);

                    assert.equal(activityStream.items.length, 4);<commit_msg>Fix race-condition in activity test migration test<commit_after>/*!
 * Copyright 2013 Apereo Foundation (AF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://opensource.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

var _ = require('underscore');
var assert = require('assert');

var ActivityConstants = require('oae-activity/lib/constants').ActivityConstants;
var ActivityDAO = require('oae-activity/lib/internal/dao');

var RestAPI = require('oae-rest');
var TestsUtil = require('oae-tests');

describe('Activity Migration', function() {

    // Rest context that can be used every time we need to make a request as a tenant admin
    var camAdminRestContext = null;


    /**
     * Function that will fill up the rest context(s)
     */
    before(function(callback) {
        camAdminRestContext = TestsUtil.createTenantAdminRestContext(global.oaeTests.tenants.cam.host);
        return callback();
    });

    /**
     * Mocks an activity
     *
     * @param  {Number}     published       The timestamp when this item was published
     * @param  {Number}     id              The ID to use for the activity
     * @param  {String}     userId          The ID of the user that will be the actor of this activity
     * @return {Activity}                   A mocked activity
     */
    var _mockActivity = function(published, id, userId) {
        var activityId = published + ':' + id;
        var activity = {};
        activity[ActivityConstants.properties.OAE_ACTIVITY_TYPE] = 'content-create';
        activity[ActivityConstants.properties.OAE_ACTIVITY_ID] = activityId;
        activity.verb = 'created';
        activity.published = published;

        activity.actor = {
            'objectType': 'user',
            'oae:id': userId
        };
        return activity;
    };

    /**
     * Creates 10 activities, 5 under the old `userId` activity stream ID and 5 under the new `userId#activity` activity stream
     *
     * @param  {String}     userId          The ID of the user for which to store the activitites
     * @param  {Function}   callback        Standard callback function
     * @param  {Object}     callback.err    Standard error object
     */
    var setUp = function(userId, callback) {
        var activities = {};

        // Re-use the same timestamp in the id to avoid race conditions
        var published = Date.now();

        // Generate 5 activities under the `u:cam:foo` activity stream
        activities[userId] = {};
        for (var i = 0; i < 5; i++) {
            var activity = _mockActivity(published, i, userId);
            activities[userId][activity[ActivityConstants.properties.OAE_ACTIVITY_ID]] = activity;
        }

        // Generate 5 activitities under the `u:cam:foo#activity` activity stream
        activities[userId + '#activity'] = {};
        for (i = 5; i < 10; i++) {
            var activity = _mockActivity(published, i, userId);
            activities[userId + '#activity'][activity[ActivityConstants.properties.OAE_ACTIVITY_ID]] = activity;
        }

        ActivityDAO.deliverActivities(activities, callback);
    };

    /**
     * Test that verifies that activities are automatically fetched from both activity streams
     */
    it('verify mixed activity streams can be retrieved', function(callback) {
        TestsUtil.generateTestUsers(camAdminRestContext, 1, function(err, users) {
            assert.ok(!err);

            var mrvisser = _.values(users)[0];
            setUp(mrvisser.user.id, function(activities) {
                assert.ok(!err);

                // Get the 4 first results, these should come from the `userId#activity` stream
                RestAPI.Activity.getCurrentUserActivityStream(mrvisser.restContext, {'limit': 4}, function(err, activityStream) {
                    assert.ok(!err);

                    assert.equal(activityStream.items.length, 4);
{'fraction_non_alphanumeric': 0.10023980815347722, 'fraction_numerical': 0.0057553956834532375, 'mean_word_length': 2.598360655737705, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '365071', 'n_tokens_mistral': 2221, 'n_tokens_neox': 2173, 'n_words': 724}