def setUp(self):

        self.dataImporter = CoMoToDataImporter(None, None, None)

        self.sameSemesterMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [],
                        'same_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5003
                            }
                        ]
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'name': 'MP1',
                'analysis_id': 50,
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }]
        }

        self.invalidSameSemesterMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [],
                        'same_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5003
                            }
                        ]
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }, {
                'name': 'invalid assignment!',
                'id': -1
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }, {
                'id': 15,
                'semester': {
                    'id': 8,
                    'season': 'Spring',
                    'year': -1
                }
            }]
        }

        self.partnerMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [],
                        'same_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5003
                            }
                        ]
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [5003],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [5001],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }]
        }

        self.solutionMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [
                            {
                                'id': 5000,
                                'score1': 80,
                                'score2': 80,
                                'submission_1_id': 5001,
                                'submission_2_id': 5004
                            }
                        ],
                        'same_semester_matches': []
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        },
                        '5004': {
                            'id': 5004,
                            'offering_id': 14,
                            'type': 'solutionsubmission'
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }]
        }

        self.crossSemesterMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5004
                            }
                        ],
                        'solution_matches': [],
                        'same_semester_matches': []
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        },
                        '5004': {
                            'id': 5004,
                            'offering_id': 15,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10004,
                                'display_name': 'Smith, Alex',
                                'netid': 'alexsmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }, {
                'id': 2,
                'analysis_id': 71,
                'name': 'MP2',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 8
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }, {
                'id': 15,
                'semester': {
                    'id': 8,
                    'season': 'Spring',
                    'year': 2012
                }
            }]
        }

        self.retakingStudentAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5004
                            }
                        ],
                        'solution_matches': [],
                        'same_semester_matches': []
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        },
                        '5004': {
                            'id': 5004,
                            'offering_id': 15,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5005': {
                            'id': 5005,
                            'offering_id': 15,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10004,
                                'display_name': 'Smith, Alex',
                                'netid': 'alexsmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }, {
                'id': 2,
                'analysis_id': 61,
                'name': 'MP2',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 8
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }, {
                'id': 15,
                'semester': {
                    'id': 8,
                    'season': 'Spring',
                    'year': 2012
                }
            }]
        }
class CoMoToDataImporterTest(ImporterTest):
    """
      Unit tests for the CoMoToDataImporter
    """

    def setUp(self):

        self.dataImporter = CoMoToDataImporter(None, None, None)

        self.sameSemesterMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [],
                        'same_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5003
                            }
                        ]
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'name': 'MP1',
                'analysis_id': 50,
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }]
        }

        self.invalidSameSemesterMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [],
                        'same_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5003
                            }
                        ]
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }, {
                'name': 'invalid assignment!',
                'id': -1
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }, {
                'id': 15,
                'semester': {
                    'id': 8,
                    'season': 'Spring',
                    'year': -1
                }
            }]
        }

        self.partnerMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [],
                        'same_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5003
                            }
                        ]
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [5003],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [5001],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }]
        }

        self.solutionMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [],
                        'solution_matches': [
                            {
                                'id': 5000,
                                'score1': 80,
                                'score2': 80,
                                'submission_1_id': 5001,
                                'submission_2_id': 5004
                            }
                        ],
                        'same_semester_matches': []
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        },
                        '5004': {
                            'id': 5004,
                            'offering_id': 14,
                            'type': 'solutionsubmission'
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }]
        }

        self.crossSemesterMatchAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5004
                            }
                        ],
                        'solution_matches': [],
                        'same_semester_matches': []
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        },
                        '5004': {
                            'id': 5004,
                            'offering_id': 15,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10004,
                                'display_name': 'Smith, Alex',
                                'netid': 'alexsmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }, {
                'id': 2,
                'analysis_id': 71,
                'name': 'MP2',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 8
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }, {
                'id': 15,
                'semester': {
                    'id': 8,
                    'season': 'Spring',
                    'year': 2012
                }
            }]
        }

        self.retakingStudentAnalysis = {
            'analysis_data': {
                50: {
                    'matches': {
                        'cross_semester_matches': [
                            {
                                'id': 5000,
                                'score1': 70,
                                'score2': 74,
                                'submission_1_id': 5001,
                                'submission_2_id': 5004
                            }
                        ],
                        'solution_matches': [],
                        'same_semester_matches': []
                    },
                    'submissions': {
                        '5001': {
                            'id': 5001,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5002': {
                            'id': 5002,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10002,
                                'display_name': 'Doe, Jane',
                                'netid': 'janedoe'
                            }
                        },
                        '5003': {
                            'id': 5003,
                            'offering_id': 14,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10003,
                                'display_name': 'Smith, Joe',
                                'netid': 'joesmith'
                            }
                        },
                        '5004': {
                            'id': 5004,
                            'offering_id': 15,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10001,
                                'display_name': 'Smith, John',
                                'netid': 'johnsmith'
                            }
                        },
                        '5005': {
                            'id': 5005,
                            'offering_id': 15,
                            'partner_ids': [],
                            'type': 'studentsubmission',
                            'student': {
                                'id': 10004,
                                'display_name': 'Smith, Alex',
                                'netid': 'alexsmith'
                            }
                        }
                    }
                }
            },
            'assignments': [{
                'id': 1,
                'analysis_id': 50,
                'name': 'MP1',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 7
                    }
                }
            }, {
                'id': 2,
                'analysis_id': 61,
                'name': 'MP2',
                'moss_analysis_pruned_offering': {
                    'semester': {
                        'id': 8
                    }
                }
            }],
            'offerings': [{
                'id': 14,
                'semester': {
                    'id': 7,
                    'season': 'Spring',
                    'year': 2011
                }
            }, {
                'id': 15,
                'semester': {
                    'id': 8,
                    'season': 'Spring',
                    'year': 2012
                }
            }]
        }


    def testSameSemesterMatchAnalysis(self):
        """
          Tests that the graph is built correctly given some simple test analysis. This
          test case considers the case of:

            * Single assignment, single analysis, single semester
            * Three submissions
            * One (same semester) submission pair match
        """

        # Setup CoMoTo data & expected graph
        analysisData = self.sameSemesterMatchAnalysis

        student1 = Student(10001, 'Smith, John', 'johnsmith')
        student2 = Student(10002, 'Doe, Jane', 'janedoe')
        student3 = Student(10003, 'Smith, Joe', 'joesmith')
        submission1 = Submission(5001)
        submission2 = Submission(5002)
        submission3 = Submission(5003)
        assignment = Assignment(1, 'MP1')
        semester = Semester(7, 'Spring', 2011)

        expectedGraph = GraphFactory.createInstance()
        expectedGraph.addNode(student1)
        expectedGraph.addNode(student2)
        expectedGraph.addNode(student3)
        expectedGraph.addNode(submission1)
        expectedGraph.addNode(submission2)
        expectedGraph.addNode(submission3)
        expectedGraph.addNode(assignment)
        expectedGraph.addNode(semester)

        expectedGraph.addBothEdges(submission1, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission2, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission3, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission1, student1, Authorship())
        expectedGraph.addBothEdges(submission2, student2, Authorship())
        expectedGraph.addBothEdges(submission3, student3, Authorship())
        expectedGraph.addBothEdges(student1, semester, Enrollment())
        expectedGraph.addBothEdges(student2, semester, Enrollment())
        expectedGraph.addBothEdges(student3, semester, Enrollment())
        expectedGraph.addBothEdges(submission1, submission3, SameSemesterMatch(5000, 72.0))
        expectedGraph.addBothEdges(semester, assignment, SemesterAssignment())

        actualGraph = self.dataImporter.buildGraph(analysisData)

        self.assertGraphsEqual(expectedGraph, actualGraph)


    def testInvalidSameSemesterMatchAnalysis(self):
        """
          Tests that the graph is built correctly given some simple test analysis. This
          test case considers the case of:

            * Single assignment, single analysis, single semester
            * Three submissions
            * One (same semester) submission pair match

          Except, also includes extraneous data that should be discarded
        """

        # Setup CoMoTo data & expected graph
        analysisData = self.invalidSameSemesterMatchAnalysis

        student1 = Student(10001, 'Smith, John', 'johnsmith')
        student2 = Student(10002, 'Doe, Jane', 'janedoe')
        student3 = Student(10003, 'Smith, Joe', 'joesmith')
        submission1 = Submission(5001)
        submission2 = Submission(5002)
        submission3 = Submission(5003)
        assignment = Assignment(1, 'MP1')
        semester = Semester(7, 'Spring', 2011)

        expectedGraph = GraphFactory.createInstance()
        expectedGraph.addNode(student1)
        expectedGraph.addNode(student2)
        expectedGraph.addNode(student3)
        expectedGraph.addNode(submission1)
        expectedGraph.addNode(submission2)
        expectedGraph.addNode(submission3)
        expectedGraph.addNode(assignment)
        expectedGraph.addNode(semester)

        expectedGraph.addBothEdges(submission1, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission2, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission3, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission1, student1, Authorship())
        expectedGraph.addBothEdges(submission2, student2, Authorship())
        expectedGraph.addBothEdges(submission3, student3, Authorship())
        expectedGraph.addBothEdges(student1, semester, Enrollment())
        expectedGraph.addBothEdges(student2, semester, Enrollment())
        expectedGraph.addBothEdges(student3, semester, Enrollment())
        expectedGraph.addBothEdges(submission1, submission3, SameSemesterMatch(5000, 72.0))
        expectedGraph.addBothEdges(semester, assignment, SemesterAssignment())

        actualGraph = self.dataImporter.buildGraph(analysisData)

        self.assertGraphsEqual(expectedGraph, actualGraph)


    def testPartnerMatchAnalysis(self):
        """
          Tests that the graph is built correctly given some simple test analysis. This
          test case considers the case of:

            * Single assignment, single analysis, single semester
            * Three submissions
            * One (same semester) submission partner pair match
        """

        # Setup CoMoTo data & expected graph
        analysisData = self.partnerMatchAnalysis

        student1 = Student(10001, 'Smith, John', 'johnsmith')
        student2 = Student(10002, 'Doe, Jane', 'janedoe')
        student3 = Student(10003, 'Smith, Joe', 'joesmith')
        submission1 = Submission(5001, {5003})
        submission2 = Submission(5002)
        submission3 = Submission(5003, {5001})
        assignment = Assignment(1, 'MP1')
        semester = Semester(7, 'Spring', 2011)

        expectedGraph = GraphFactory.createInstance()
        expectedGraph.addNode(student1)
        expectedGraph.addNode(student2)
        expectedGraph.addNode(student3)
        expectedGraph.addNode(submission1)
        expectedGraph.addNode(submission2)
        expectedGraph.addNode(submission3)
        expectedGraph.addNode(assignment)
        expectedGraph.addNode(semester)

        expectedGraph.addBothEdges(submission1, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission2, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission3, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission1, student1, Authorship())
        expectedGraph.addBothEdges(submission2, student2, Authorship())
        expectedGraph.addBothEdges(submission3, student3, Authorship())
        expectedGraph.addBothEdges(student1, semester, Enrollment())
        expectedGraph.addBothEdges(student2, semester, Enrollment())
        expectedGraph.addBothEdges(student3, semester, Enrollment())
        expectedGraph.addBothEdges(submission1, submission3, PartnerMatch(5000, 72.0))
        expectedGraph.addBothEdges(semester, assignment, SemesterAssignment())

        actualGraph = self.dataImporter.buildGraph(analysisData)

        self.assertGraphsEqual(expectedGraph, actualGraph)


    def testSolutionMatchAnalysis(self):
        """
          Tests that the graph is built correctly given some simple test analysis. This
          test case considers the case of:

            * Single assignment, single analysis, single semester
            * Three submissions
            * One (same semester) solution match
        """

        # Setup CoMoTo data & expected graph
        analysisData = self.solutionMatchAnalysis

        student1 = Student(10001, 'Smith, John', 'johnsmith')
        student2 = Student(10002, 'Doe, Jane', 'janedoe')
        student3 = Student(10003, 'Smith, Joe', 'joesmith')
        submission1 = Submission(5001)
        submission2 = Submission(5002)
        submission3 = Submission(5003)
        solutionSubmission = Submission(5004, None, True)
        assignment = Assignment(1, 'MP1')
        semester = Semester(7, 'Spring', 2011)

        expectedGraph = GraphFactory.createInstance()
        expectedGraph.addNode(student1)
        expectedGraph.addNode(student2)
        expectedGraph.addNode(student3)
        expectedGraph.addNode(submission1)
        expectedGraph.addNode(submission2)
        expectedGraph.addNode(submission3)
        expectedGraph.addNode(solutionSubmission)
        expectedGraph.addNode(assignment)
        expectedGraph.addNode(semester)

        expectedGraph.addBothEdges(submission1, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission2, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission3, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(solutionSubmission, assignment, AssignmentSubmission())
        expectedGraph.addBothEdges(submission1, student1, Authorship())
        expectedGraph.addBothEdges(submission2, student2, Authorship())
        expectedGraph.addBothEdges(submission3, student3, Authorship())
        expectedGraph.addBothEdges(student1, semester, Enrollment())
        expectedGraph.addBothEdges(student2, semester, Enrollment())
        expectedGraph.addBothEdges(student3, semester, Enrollment())
        expectedGraph.addBothEdges(submission1, solutionSubmission, SolutionMatch(5000, 80))
        expectedGraph.addBothEdges(semester, assignment, SemesterAssignment())

        actualGraph = self.dataImporter.buildGraph(analysisData)

        self.assertGraphsEqual(expectedGraph, actualGraph)


    def testCrossSemesterMatchAnalyses(self):
        """
          Tests that the graph is built correctly given some more complex test analysis. This
          test case considers the case of:

            * Two assignments, two analyses, two semesters
            * Four submissions
            * One (cross semester) match
        """

        # Setup CoMoTo data & expected graph
        analysisData = self.crossSemesterMatchAnalysis

        student1 = Student(10001, 'Smith, John', 'johnsmith')
        student2 = Student(10002, 'Doe, Jane', 'janedoe')
        student3 = Student(10003, 'Smith, Joe', 'joesmith')
        student4 = Student(10004, 'Smith, Alex', 'alexsmith')
        submission1 = Submission(5001)
        submission2 = Submission(5002)
        submission3 = Submission(5003)
        submission4 = Submission(5004)
        assignment1 = Assignment(1, 'MP1')
        assignment2 = Assignment(2, 'MP2')
        semester1 = Semester(7, 'Spring', 2011)
        semester2 = Semester(8, 'Spring', 2012)

        expectedGraph = GraphFactory.createInstance()
        expectedGraph.addNode(student1)
        expectedGraph.addNode(student2)
        expectedGraph.addNode(student3)
        expectedGraph.addNode(student4)
        expectedGraph.addNode(submission1)
        expectedGraph.addNode(submission2)
        expectedGraph.addNode(submission3)
        expectedGraph.addNode(submission4)
        expectedGraph.addNode(assignment1)
        expectedGraph.addNode(assignment2)
        expectedGraph.addNode(semester1)
        expectedGraph.addNode(semester2)

        expectedGraph.addBothEdges(submission1, assignment1, AssignmentSubmission())
        expectedGraph.addBothEdges(submission2, assignment1, AssignmentSubmission())
        expectedGraph.addBothEdges(submission3, assignment1, AssignmentSubmission())
        expectedGraph.addBothEdges(submission4, assignment2, AssignmentSubmission())
        expectedGraph.addBothEdges(submission1, student1, Authorship())
        expectedGraph.addBothEdges(submission2, student2, Authorship())
        expectedGraph.addBothEdges(submission3, student3, Authorship())
        expectedGraph.addBothEdges(submission4, student4, Authorship())
        expectedGraph.addBothEdges(student1, semester1, Enrollment())
        expectedGraph.addBothEdges(student2, semester1, Enrollment())
        expectedGraph.addBothEdges(student3, semester1, Enrollment())
        expectedGraph.addBothEdges(student4, semester2, Enrollment())
        expectedGraph.addBothEdges(semester1, assignment1, SemesterAssignment())
        expectedGraph.addBothEdges(semester2, assignment2, SemesterAssignment())

        # Every type of edge should be symmetric, except for the cross-semester match (since current submissions can
        # match past submissions, but not vice versa)
        expectedGraph.addEdge(submission1, submission4, CrossSemesterMatch(5000, 72.0))

        # Test
        actualGraph = self.dataImporter.buildGraph(analysisData)

        # Verify
        self.assertGraphsEqual(expectedGraph, actualGraph)


    def testRetakingStudentAnalyses(self):
        """
          Tests that the graph is built correctly given some more complex test analysis. This
          test case considers the case of:

            * Two assignments, two analyses, two semesters
            * Five submissions, two by a single student (in two semesters)
            * One (cross semester) match between two submissions from the same student

          In this case, the match should be removed
        """

        # Setup CoMoTo data & expected graph
        analysisData = self.retakingStudentAnalysis

        student1 = Student(10001, 'Smith, John', 'johnsmith', True)
        student2 = Student(10002, 'Doe, Jane', 'janedoe')
        student3 = Student(10003, 'Smith, Joe', 'joesmith')
        student4 = Student(10004, 'Smith, Alex', 'alexsmith')
        submission2 = Submission(5002)
        submission3 = Submission(5003)
        submission4 = Submission(5004)
        submission5 = Submission(5005)
        assignment1 = Assignment(1, 'MP1')
        assignment2 = Assignment(2, 'MP2')
        semester1 = Semester(7, 'Spring', 2011)
        semester2 = Semester(8, 'Spring', 2012)

        expectedGraph = GraphFactory.createInstance()
        expectedGraph.addNode(student1)
        expectedGraph.addNode(student2)
        expectedGraph.addNode(student3)
        expectedGraph.addNode(student4)
        expectedGraph.addNode(submission2)
        expectedGraph.addNode(submission3)
        expectedGraph.addNode(submission4)
        expectedGraph.addNode(submission5)
        expectedGraph.addNode(assignment1)
        expectedGraph.addNode(assignment2)
        expectedGraph.addNode(semester1)
        expectedGraph.addNode(semester2)

        expectedGraph.addBothEdges(submission2, assignment1, AssignmentSubmission())
        expectedGraph.addBothEdges(submission3, assignment1, AssignmentSubmission())
        expectedGraph.addBothEdges(submission4, assignment2, AssignmentSubmission())
        expectedGraph.addBothEdges(submission5, assignment2, AssignmentSubmission())
        expectedGraph.addBothEdges(submission2, student2, Authorship())
        expectedGraph.addBothEdges(submission3, student3, Authorship())
        expectedGraph.addBothEdges(submission4, student1, Authorship())
        expectedGraph.addBothEdges(submission5, student4, Authorship())
        expectedGraph.addBothEdges(student1, semester2, Enrollment())
        expectedGraph.addBothEdges(student2, semester1, Enrollment())
        expectedGraph.addBothEdges(student3, semester1, Enrollment())
        expectedGraph.addBothEdges(student4, semester2, Enrollment())
        expectedGraph.addBothEdges(semester1, assignment1, SemesterAssignment())
        expectedGraph.addBothEdges(semester2, assignment2, SemesterAssignment())

        # Test
        actualGraph = self.dataImporter.buildGraph(analysisData)

        # Verify
        self.assertGraphsEqual(expectedGraph, actualGraph)